我正在编写一个 Web 应用程序(基于服务器的应用程序),其中我有一个 dao 层、服务层和应用程序层。我应该如何接管延迟初始化异常,这是由于从 dao 层返回的实体与在返回它的方法内打开的会话有关,并且还在那里关闭,这使得实体分离。接下来是在不同层之间共享休眠实体是安全的。让我问这个问题的是场景:例如,假设我有一个休眠实体,它与其他实体具有一对一的关联。并假设 dao 将其传递给服务层到应用程序层。现在,如果我尝试通过传递的实体 getter 方法在应用层中获取此关联实体,一个数据库查询被触发,我认为这与“关注点分离”混淆了,因为与数据库相关的操作应该被限制在 dao 层。我对吗?在我通过内存数据库对我的 dao 层进行单元测试时,我发现了上述问题。我的场景是,我有一个名为 RegisteredUser 的 pojo 类,其中包含以下字段:(id、username、firstname、lastname、passwHash、email、StudyCentre)。StudyCentre 是另一个实体,它通过一对一映射与 RegistereUser 关联,用户名是 naturalid。我想要的是两种类型的读取操作,第一种是我需要通过自然 ID 在没有学习中心的情况下获取用户详细信息,第二种是通过自然 ID 再次获取完整的用户字段。在这里制作两个单独的 DTO 是一个好主意,并将它们跨层传递。道实现者:package com.ignoubadhega.dao.impl;import org.hibernate.HibernateException;import org.hibernate.Session;import org.hibernate.SessionFactory;import com.ignoubadhega.dao.RegisteredUserDAO;import com.ignoubadhega.pojos.RegisteredUser;public class RegisteredUserDAOImpl implements RegisteredUserDAO { private SessionFactory sessionFactory; public RegisteredUserDAOImpl(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Override public void addUser(RegisteredUser user) { try (Session session = sessionFactory .openSession()) { session.beginTransaction(); session.persist(user); session.getTransaction().commit(); } catch (HibernateException except) { except.printStackTrace(); } } @Override public RegisteredUser getUserByUserName(String username, boolean doesStudyCentereNeeded) { try (Session session = sessionFactory .openSession()) { RegisteredUser user = session .bySimpleNaturalId(RegisteredUser.class).load(username); if (doesStudyCentereNeeded) { user.setStudyCentre(user.getStudyCentre()); } return user; } catch (HibernateException except) { except.printStackTrace(); } return null; }
1 回答
森林海
TA贡献2011条经验 获得超2个赞
我应该如何接管延迟初始化异常,这是由于从 dao 层返回的实体与在返回它的方法内打开的会话有关,并且还在那里关闭,这使得实体分离。
您可以通过在服务或应用层中打开和关闭会话并在单个事务中完成所有工作来处理这个问题。
跨不同层共享休眠实体是否安全
是的。不安全的是跨多个线程使用实体实例,因为实体不是线程安全的。
一个数据库查询被触发,我认为这与“关注点分离”混淆了,因为与数据库相关的操作应该被限制在 dao 层。我对吗?
不。服务层不包含任何代码来触发此数据库查询。它是透明地发生的,无需服务层关心它,并且因为您选择使关联变得惰性。
在这里制作两个单独的 DTO 是一个好主意,并将它们跨层传递。
不会。DTO 对于在不同应用程序之间传输数据很有用。在您的应用程序中,使用托管实体是正确的方法。
我想让我的服务层(尚未实现)与特定于休眠的事物(如会话和数据库相关操作(CRUD))隔离开来。我怎样才能实现它。
通过使用 Spring 或 Java EE(或任何其他具有此功能的框架),它们允许使用声明性事务并在调用事务方法时为您处理打开/关闭会话和事务的任务。
您还应该避免使用专有的 Session API,而是使用标准的 JPA API。
添加回答
举报
0/150
提交
取消
