- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写一个Web应用程序(基于服务器的应用程序),其中有一个dao层、服务层和应用程序层。我应该如何接管惰性初始化异常,该异常是由于从 dao 层返回的实体与返回它的方法内部打开的 session 有关并且也在那里关闭而导致的,这使得实体分离。接下来的事情是可以安全地跨不同层共享 hibernate 实体。是什么让我问这个问题是场景:例如假设我有一个 hibernate 实体与某个其他实体具有一对一的关联。假设dao将其传递给服务层到应用层。现在,如果我尝试通过传递的实体 getter 方法在应用程序层获取此关联实体,则会触发数据库查询,我认为这会扰乱“关注点分离”,因为数据库相关操作应限制在 dao 层。我说得对吗?
我在通过内存数据库对我的 dao 层进行单元测试时发现了上述问题。我的场景是,我有一个名为 RegisteredUser 的 pojo 类,其字段为:(id、用户名、名字、姓氏、passwHash、电子邮件、StudyCentre)。 StudyCentre 是另一个实体,它通过一对一映射与 RegistereUser 关联,用户名是naturalid。我想要的是两种类型的读取操作,第一种是我需要通过自然ID在没有学习中心的情况下获取用户详细信息,第二种是通过自然ID再次获取完整的用户字段。在这里制作两个单独的 DTO 并跨层传递它们是一个好主意。
注册用户实体:
package com.ignoubadhega.pojos;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.NaturalId;
@Entity
@Table(name = "registered_user")
@DynamicUpdate
public class RegisteredUser {
private Long dbUserId;
private String userName;
private String passwHash;
private String firstName;
private String lastName;
private String email;
private StudyCentre studyCentre;
RegisteredUser() {
}
public RegisteredUser(
String userName, String passwHash, String firstName,
String lastName, String email
) {
super();
this.userName = userName;
this.passwHash = passwHash;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "db_user_id")
public Long getDbUserId() {
return dbUserId;
}
@Override
public String toString() {
return "RegisteredUser [dbUserId="
+ dbUserId
+ ", userName="
+ userName
+ ", passwHash="
+ passwHash
+ ", firstName="
+ firstName
+ ", lastName="
+ lastName
+ ", email="
+ email
+ "]";
}
public void setDbUserId(Long dbUserId) {
this.dbUserId = dbUserId;
}
@Column(name = "username", nullable = false, unique = true)
@NaturalId
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Column(name = "passw_hash", nullable = false)
public String getPasswHash() {
return passwHash;
}
public void setPasswHash(String passwHash) {
this.passwHash = passwHash;
}
@Column(name = "first_name", nullable = false)
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@Column(name = "last_name", nullable = false)
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Column(name = "email", nullable = false, unique = true)
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "db_study_centre_id", nullable = false)
public StudyCentre getStudyCentre() {
return studyCentre;
}
public void setStudyCentre(StudyCentre studyCentre) {
this.studyCentre = studyCentre;
}
}
Dao 实现者:
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;
}
@Override
public void deleteUser(RegisteredUser user) {
try (Session session = sessionFactory
.openSession()) {
session.beginTransaction();
session.delete(user);
session.getTransaction().commit();
} catch (HibernateException except) {
except.printStackTrace();
}
}
@Override
public void updateUser(RegisteredUser user) {
try (Session session = sessionFactory
.openSession()) {
session.beginTransaction();
session.update(user);
session.getTransaction().commit();
} catch (HibernateException except) {
except.printStackTrace();
}
}
}
发现延迟初始化问题的TestCase:
@Test
@DisplayName(
"User through its natural id 'username' assuming the user"
+ " is persistent in the database is successful"
)
void test_fetching_a_persistent_user_through_username_is_successful() {
try (Session session = sessionFactory.openSession()) {
session.beginTransaction();
session.persist(user);
session.getTransaction().commit();
RegisteredUser retrievedUser =
dao.getUserByUserName("prav", true);
assertNotNull(retrievedUser);
assert_actual_user_and_retrieved_user_fields_are_equal(user,
retrievedUser);
} catch (HibernateException except) {
except.printStackTrace();
}
}
private static void assert_actual_user_and_retrieved_user_fields_are_equal(
RegisteredUser actualUser, RegisteredUser userRetrieved
) throws MultipleFailuresError {
assertAll("user fields",
() -> assertEquals(actualUser.getUserName(),
userRetrieved.getUserName()),
() -> assertEquals(actualUser.getPasswHash(),
userRetrieved.getPasswHash()),
() -> assertEquals(actualUser.getFirstName(),
userRetrieved.getFirstName()),
() -> assertEquals(actualUser.getLastName(),
userRetrieved.getLastName()),
() -> assertEquals(actualUser.getEmail(),
userRetrieved.getEmail()),
() -> {
StudyCentre retrievedCentre =
userRetrieved.getStudyCentre();
assertNotNull(retrievedCentre);
assertAll("user study centre assosciated",
() -> assertEquals(
actualUser.getStudyCentre().getData()
.getStudyCentreName(),
retrievedCentre.getData()
.getStudyCentreName()),
() -> assertEquals(
actualUser.getStudyCentre().getData()
.getRegionalCentreCode(),
retrievedCentre.getData()
.getRegionalCentreCode()));
});
}
我希望保持我的服务层(尚未实现)与 Hibernate 特有的事物(如 session 和数据库相关操作(CRUD))隔离。我怎样才能实现它。我应该遵循什么设计模式吗?我是 hibernate 新手。如果我在任何地方做错了什么,请指导我。我尝试在谷歌上找到类似的帖子,但未能获得有关该问题的任何见解。
最佳答案
how should i take over the lazy initialization exception, caused due to the fact that entity returned from dao layer is concerned with the session opened inside the method from where it is returned and also closed there which makes the entity detached.
您可以通过在服务或应用程序层中打开和关闭 session ,并在单个事务中完成所有工作来处理该问题。
is it safe to share the hibernate entities across different layer
是的。不安全的是跨多个线程使用实体实例,因为实体不是线程安全的。
a database query is fired which i think is messing up with the "seperation of concerns" as database related operation should be constrained to the dao layer. am i right?
没有。服务层不包含任何触发此数据库查询的代码。它是透明发生的,服务层不必关心它,因为您选择使关联变得惰性。
is making two seperate DTOs a good idea here and passing them across layers.
没有。 DTO 对于在不同的应用程序之间传输数据非常有用。在您的应用程序中,使用托管实体是正确的方法。
i want to keep my service layer(not yet implemented) to be isolated from things specific to hibernate like sessions and database related operations(CRUD). how can i achieve it.
通过使用 Spring 或 Java EE(或任何其他具有此功能的框架),它们允许使用声明性事务,并在调用事务方法时为您处理打开/关闭 session 和事务的任务。
您还应该避免使用专有的 Session API,而使用标准的 JPA API。
关于java - 我应该如何处理 dao 层中延迟初始化的 Hibernate 实体以及在不同层中共享状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55740190/
我有组件需要更新客户和客户地址的数据库(通过 JDBC)。从 CustomerDAO 调用 CustomerAddressDAO 是否合适?或者创建一个单独的“CustomerDataManager”
任何人都可以解释MS Access 2007中DAO.Recordset,DAO.Recordsets和DAO.Recordset2之间的区别吗?基本上使用记录集。...举一个例子,使它更清晰。我从“
所以我正在编写一个个人项目来学习 Web 编程,并且我遇到了 DAO 模式。我构建了一些类(模型),并且像几乎所有程序一样,它们是嵌套的(例如:类 Payment 具有对 Author 实例的引用)。
我有一个基本问题。 我一直在创建关注点分离的 DAO。每个 DAO 都专注于上下文中的 BusinessObject。我的问题是如何在另一个 DAO 中使用一个 DAO 方法。我认为这是错误的,但没有
有没有办法使用 Android Room Persistence Library 将 DAO 作为依赖项添加到其他 DAO 中,也许是使用 Dagger2?我试图避免在使用事务对多个表执行操作的 DA
通常,我会尝试以一种完全依赖于自身的方式来构建我的 DAO 类。它们可以与多个表交互,但前提是数据与基础对象相关。例如,假设我有一个约会对象,约会 DAO 从约会表中提取数据。如果约会表是一个服务 i
在学校学习过 Java 后,我对 DAO 模式( Data access object )非常熟悉。然而在工作中我使用.NET。在 .NET 中,经常讨论 DAL( Data Access Layer
我一直在尝试按照以下步骤创建一个通用的 DAO: http://www.ibm.com/developerworks/java/library/j-genericdao/index.html 不过,我
Java EE 中的最佳实践是什么? 在服务(或管理器)类中创建 DAO 类的实例 SalesDAO salesDao = new SalesDAOImpl(); salesDao.findCusto
这有道理吗? 假设我需要从 DB 中获取一个对象,该对象与另一个对象有关系(由 DB 中的外键表示,并由我的域对象中的组合表示)。如果在我的第一个 DAO 中,我为对象 1 获取数据,然后为对象 2
我目前正在为应用程序创建数据访问层。此应用程序最初将连接到 Oracle 数据库,但稍后也会连接到 DB2 数据库。 为了连接到数据库,我将使用 JDBC。在这个时候我正在考虑我的选择。在我看来,我有
我正在 JSF 中设计一些数据“块” 我从每个块的 Java bean 中获取我的数据。 我的问题是我的块从多个表中获取数据。 例如: 描述 的块客户的个人资料 由组成: 客户名称(在表 客户 中)
将 DAO 类与应用程序代码中实际实例化的 DAO 类分开有什么好处,即为什么不在这样的场景中直接实例化 DAO 类: Class CreateIocContainer{ p s v main
我正在为我的 DataNucleus JDO DAO 创建通用 DAO。通用 DAO 将执行获取、更新、删除、创建操作和一些其他通用操作,因此这些实现可以在更具体的 DAO 中进行扩展。 是否有可能以
这可能是一件非常微不足道的事情,但我是一些面向对象模式的新手。 简而言之,在另一个 DAO 中使用一个 DAO 中的方法是一种不好的做法吗?我试图在 DAO 中创建一个实体,但发现仅使用该 DAO 很
我参与了一个 Java 项目,该项目从不同的支付代理获取支付信息,对其进行处理并将其存储到我们的计费系统(数据库)中。 由于我们有不同的代理,因此支付协议(protocol)也不同,因此我们有时有相似
考虑以下 Room DAO @Dao public abstract class JobDao { @Insert public abstract long insert( Job v
我有一个“容器”类,其字段包含在多个数据库表中,我使用 DAO 模式来访问数据。 问题是,我应该为这个“容器”类创建一个 DAO,还是每个表有一个 DAO 并合并它们的数据更好? 最佳答案 您应该根据
我们正在通过 @Service 和 @Component 注释使用 Spring @Autowired 改造一个新的面向服务的架构。 我一直在和我的同事争论不让每个 DAO 都有接口(interfac
我有通用的 DAO: @NoRepositoryBean interface ICrudDao extends Repository { void delete(T deleted);
我是一名优秀的程序员,十分优秀!