Java 我应该如何处理dao层中延迟初始化的Hibernate实体和不同层中的共享状态

Java 我应该如何处理dao层中延迟初始化的Hibernate实体和不同层中的共享状态,java,hibernate,jpa-2.0,dao,Java,Hibernate,Jpa 2.0,Dao,我正在编写一个web应用程序(基于服务器的应用程序),其中有一个dao层、服务层和应用程序层。我应该如何接管延迟初始化异常,这是由于从dao层返回的实体与在方法内部打开的会话有关,该会话从该方法返回,并在该方法中关闭,从而使实体分离。 接下来,跨不同层共享hibernate实体是安全的。让我问这个问题的是场景:例如,假设我有一个hibernate实体与其他实体有一对一的关联。假设dao将其传递给服务层和应用层。现在,如果我试图通过传递的实体getter方法在应用程序层中获取这个关联实体,就会触发

我正在编写一个web应用程序(基于服务器的应用程序),其中有一个dao层、服务层和应用程序层。我应该如何接管延迟初始化异常,这是由于从dao层返回的实体与在方法内部打开的会话有关,该会话从该方法返回,并在该方法中关闭,从而使实体分离。 接下来,跨不同层共享hibernate实体是安全的。让我问这个问题的是场景:例如,假设我有一个hibernate实体与其他实体有一对一的关联。假设dao将其传递给服务层和应用层。现在,如果我试图通过传递的实体getter方法在应用程序层中获取这个关联实体,就会触发一个数据库查询,我认为这会破坏“关注点分离”,因为与数据库相关的操作应该限制在dao层。我说得对吗

在通过内存数据库对dao层进行单元测试的过程中,我发现了上述问题。我的场景是,我有一个名为RegisteredUser的pojo类,它包含以下字段:(id、用户名、名字、姓氏、密码、电子邮件、StudyCenter)。StudyCenter是另一个实体,它通过一对一映射与RegisterUser关联,用户名是自然ID。 我想要的是两种类型的读取操作,第一种是我需要通过natural id获取用户详细信息,而不需要StudyCenter,第二种是通过naturalid再次获取完整的用户字段。在这里制作两个独立的DTO并将它们跨层传递是一个好主意

注册用户实体:

package com.ignoubadhega.pojos;
导入javax.persistence.CascadeType;
导入javax.persistence.Column;
导入javax.persistence.Entity;
导入javax.persistence.FetchType;
导入javax.persistence.GeneratedValue;
导入javax.persistence.GenerationType;
导入javax.persistence.Id;
导入javax.persistence.JoinColumn;
导入javax.persistence.OneToOne;
导入javax.persistence.Table;
导入org.hibernate.annotations.DynamicUpdate;
导入org.hibernate.annotations.d;
@实体
@表(name=“注册用户”)
@动态铜日期
公共类注册器{
私有长dbUserId;
私有字符串用户名;
私有字符串passwHash;
私有字符串名;
私有字符串lastName;
私人字符串电子邮件;
私人学生中心学生中心;
RegisteredUser(){
}
公共注册用户(
字符串用户名、字符串密码、字符串名字、,
字符串lastName,字符串email
) {
超级();
this.userName=用户名;
this.passwHash=passwHash;
this.firstName=firstName;
this.lastName=lastName;
this.email=电子邮件;
}
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(name=“db\u user\u id”)
公共长getDbUserId(){
返回dbUserId;
}
@凌驾
公共字符串toString(){
return“RegisteredUser[dbUserId=”
+数据库用户ID
+“,用户名=”
+用户名
+“,passwHash=”
+逾越节
+,firstName=
+名字
+,lastName=
+姓氏
+“,电子邮件=”
+电子邮件
+ "]";
}
public void setDbUserId(长dbUserId){
this.dbUserId=dbUserId;
}
@列(name=“username”,nullable=false,unique=true)
@归化
公共字符串getUserName(){
返回用户名;
}
public void setUserName(字符串用户名){
this.userName=用户名;
}
@列(name=“passw\u hash”,null=false)
公共字符串getPasswHash(){
返回passwHash;
}
公共void setPasswHash(字符串passwHash){
this.passwHash=passwHash;
}
@列(name=“first\u name”,nullable=false)
公共字符串getFirstName(){
返回名字;
}
public void setFirstName(字符串firstName){
this.firstName=firstName;
}
@列(name=“last_name”,nullable=false)
公共字符串getLastName(){
返回姓氏;
}
public void setLastName(字符串lastName){
this.lastName=lastName;
}
@列(name=“email”,nullable=false,unique=true)
公共字符串getEmail(){
回复邮件;
}
公用电子邮件(字符串电子邮件){
this.email=电子邮件;
}
@OneToOne(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name=“db\U研究\U中心\U id”,null=false)
公共学习中心GetStudyCenter(){
返回学习中心;
}
公共无效设置学生中心(学生中心学生中心){
this.studyCentre=studyCentre;
}
}
Dao实现者:

package com.ignoubadhega.dao.impl;
导入org.hibernate.hibernateeexception;
导入org.hibernate.Session;
导入org.hibernate.SessionFactory;
导入com.ignoubadhega.dao.RegisteredUserDAO;
导入com.ignoubadhega.pojos.RegisteredUser;
公共类RegisteredUserDAOImpl实现RegisteredUserDAO{
私人会话工厂会话工厂;
公共注册器duserdaoimpl(SessionFactory SessionFactory){
this.sessionFactory=sessionFactory;
}
@凌驾
public void addUser(RegisteredUser用户){
try(会话=会话工厂)
.openSession()){
session.beginTransaction();
session.persist(用户);
session.getTransaction().commit();
}捕获(HibernateeException除外){
除了.printStackTrace();
}
}
@凌驾
公共RegisteredUser getUserByUserName(字符串用户名,布尔DoesStudyCenter){
try(会话=会话工厂)