hibernate - 尽管配置良好,@OneToMany 延迟加载仍不起作用
问题描述
Java 8 春季启动 2.0.5
我有以下配置,我确信这是正确的。在调试期间,我可以从 UserInformations 中延迟加载的工具集合中获取值。我读到调试正在执行额外的提取以使用户能够从数据库中获取值,但是System.out.print
在我的端点中简单应该会失败。我想延迟加载集合,@OneToMany
因为现在正在加载急切,如果我将有更多数据获取单个UserInformation
将很长。@OneToMany
默认情况下是懒惰的,但在我的示例中,它的工作很热切,我不知道为什么要修复它来获取懒惰。
这是我的课:
@Getter
@Setter
@NoArgsConstructor
public class ElectricTool {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@NotBlank
@NotEmpty
@Size(max = 64)
private String name;
@ManyToOne
private UserInformation userInformation;
public ElectricTool(String name) {
this.name = name;
}
}
@Getter
@Setter
@Entity
public class UserInformation {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@NotEmpty
@NotBlank
@Size(max = 32)
private String firstName;
@OneToMany(mappedBy = "userInformation")
private Set<ElectricTool> electricTools;
public UserInformation() {
this.electricTools = new HashSet<>();
}
public UserInformation(String firstName) {
this.firstName = firstName;
this.electricTools = new HashSet<>();
}
}
@Repository
public interface UserInformationRepository extends
JpaRepository<UserInformation, Long> {}
@Repository
public interface ElectricToolRepository extends
JpaRepository<ElectricTool, Long> {}
@RestController
@RequestMapping(value = "/lazy")
public class LazyController {
private UserInformationRepository userInformationRepository;
private ElectricToolRepository electricToolRepository;
public LazyController(UserInformationRepository userInformationRepository, ElectricToolRepository electricToolRepository) {
this.userInformationRepository = userInformationRepository;
this.electricToolRepository = electricToolRepository;
}
@GetMapping
public void checkLazy() {
userInformationRepository.findAll().get(0).getElectricTools().stream().findFirst().get();
}
}
配置
spring.datasource:
url: jdbc:postgresql://localhost:5432/lazy
username: postgres
password: admin
spring.jpa:
show-sql: true
hibernate.ddl-auto: create-drop
database-platform: org.hibernate.dialect.PostgreSQLDialect
properties.hibernate.jdbc.lob.non_contextual_creation: true
System.out.print 的结果: 这应该是延迟加载异常
调试结果: 调试时我可以使用电动工具,但它应该抛出延迟加载异常
当我打开 SQL 的显示并更改控制器中的方法以直接从 userInformation 获取electricTool 时,它返回对象但应该抛出异常并且 sql 看起来像这样
select userinform0_.id as id1_1_, userinform0_.first_name as first_na2_1_ from user_information userinform0_
select electricto0_.user_information_id as user_inf3_0_0_, electricto0_.id as id1_0_0_, electricto0_.id as id1_0_1_, electricto0_.name as name2_0_1_, electricto0_.user_information_id as user_inf3_0_1_ from electric_tool electricto0_ where electricto0_.user_information_id=?
select userinform0_.id as id1_1_, userinform0_.first_name as first_na2_1_ from user_information userinform0_
当您问我为什么我认为在询问@OneToMany 注释的集合中的元素时我应该得到延迟获取异常时,我只想向您展示与上面相同的配置,但在第二个项目中可以正常工作,但让我们看看代码
@Entity
@Getter
@Setter
public class UserInformation {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
@OneToMany(mappedBy = "userInformation")
private Set<Address> addresses;
public UserInformation() {
this.addresses = new HashSet<>();
}
public UserInformation(String firstName) {
this.firstName = firstName;
this.addresses = new HashSet<>();
}
}
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String city;
@ManyToOne
private UserInformation userInformation;
public Address(String city) {
this.city = city;
}
}
@Repository
public interface UserInformationRepository extends JpaRepository<UserInformation, Long> {
}
@Repository
public interface AddressRepository extends JpaRepository<Address, Long> {
}
配置
spring.datasource:
url: jdbc:postgresql://localhost:5432/specification
username: postgres
password: admin
spring.jpa:
show-sql: true
hibernate.ddl-auto: create-drop
database-platform: org.hibernate.dialect.PostgreSQLDialect
properties.hibernate.jdbc.lob.non_contextual_creation: true
当我尝试执行那段代码时:
userInformationRepository.findAll()
我得到 LazyInitializationException ,这是我想在第一个示例中获得的行为。那么第一个示例中的错误在哪里,因为 findAll 方法给了我调试器中的所有嵌套关系
另外,当我执行与第一个示例相同的执行时,我得到 LazyInitializationException
userInformationRepository.findAll().get(0).getAddresses().stream().findFirst().get();
failed to lazily initialize a collection of role: com.specification.specification.entity.borrow.UserInformation.addresses, could not initialize proxy - no Session
解决方案
正如@Abdullah Khan 所说,问题已解决,sql 日志正确显示所有这些示例都有效,但 Intellij 的调试器会获取对象的必要关系,关闭主题。谢谢大家的帮助:)
推荐阅读
- arrays - 在数组 A 中,我们有一个反转 (i, j)。为什么我们在数组中至少有 ji 反转?
- python - Selenium - 滚动并单击
- javascript - 如何返回 2 个属性值并将它们串在一起
- r - R从宽到长旋转多列
- postgresql - Postgres,Typeorm保存在索引数组而不是关系字段中
- c++ - 有没有办法一致地对类型模板参数进行排序?
- python - 如何汇总熊猫数据框中的销售额?
- ios - Visual Studio MacOS - iOS 应用签名、配置和 TeamID - MSAL 身份验证
- electron - Electron:如何将 API 响应的 ZPLCode 值直接打印到标签打印机?
- discord - 如何让机器人对自己的嵌入做出反应?