Java 8 Spring Boot 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的结果: This should be lazy loading exception
调试结果: While debugging i have access to electric tool but it should throw lazy loading exception
当我打开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
答案 0 :(得分:0)
它将仅打印该类的地址/引用。如果要打印值,请重写如下的toString方法。
@Override
public String toString()
{
return new ToStringBuilder(this)
.append("name", name)
.append("etc", etc)
.toString();
}
还在onetomany映射中添加级联类型和访存类型。
@OneToMany(mappedBy = "userInformation",cascade=CascadeType.ALL,fetch=FetchType.EAGER)
答案 1 :(得分:0)
问题已解决,就像@Abdullah Khan所说的那样,SQL日志正确显示了所有这些示例,但Intellij的调试器获取了对象的必要关系,主题已关闭。谢谢大家的帮助:)