当前位置: 首页 > 面试题库 >

在hibernate / jpa最佳实践问题中将独立实体或新实体与现有实体合并

娄嘉石
2023-03-14
问题内容

当业务层创建一个新的实体时,该实体在逻辑上表示应该更新的现有实体的实例(例如,它们共享相同的业务密钥),这是合并不良做法的方法吗?

public User add(User user){

    User existingUser = getUserDao().findByBusinessKey(user.getBusinessKey(), false);
    user.setId(existingUser.getId());

    user = getUserDao().merge(user);

    return user;
}

我问是因为在分离的实体上显式设置ID对我来说很奇怪,但是即使User实体的equals和hashcode方法得到了适当实现,在这里设置ID是确保合并发生的唯一方法。

有更好的做法吗?

此方法是否有特定的缺点,以后会困扰我?

谢谢参观!


问题答案:

代码起作用 ,但是不必在分离的实体上显式设置ID。典型的Hibernate应用程序具有处理两种情况的“保存”方法:

  1. 用户想要创建一个新用户,因此该应用程序创建一个ID为“ null”的User对象。
  2. 用户查询了一个用户列表,并且正在选择一个进行编辑。在这种情况下,应用程序会进行查询,并将对象传播到“保存”方法。该对象将具有一个ID,并且代码将对其应用新的值。

看起来您的代码中的某些内容没有以典型方式执行第二种情况。如果“用户”对象来自某个先​​前的Hibernate查询(通过用户单击“编辑用户”或类似内容触发),则该对象已经具有ID。因此,仅merge(user)需要呼叫。

我通常会这样:

if (user.getId() == null)
  em.persist(user);
else
  user = em.merge(user);

然后,我添加代码来处理乐观锁定问题(另一个会话更新了对象)和唯一约束问题(另一个会话尝试使用相同的业务密钥来持久化某些内容)。

诸如Seam之类的框架可以使这一过程变得更加简单,因为它们在控制器bean方法之间传播了Hibernate会话。因此,甚至不需要“合并”。



 类似资料:
  • 对于新学生和新课程的情况,它工作得很好,但是在新课程和现有学生的情况下,我会从数据库中抛出一个唯一的约束冲突。关系类似于下面。 在持久化之前,我尝试使用entitymanager查找一个学生,如果该学生存在,则使用该实例而不是新的学生实例。这也不起作用,它仍然尝试执行插入而不是更新

  • 举一个非常简单的一对多关系的例子(国家 实体的方法: 应该注意,<code>orphanRemove</code>设置为<code>true</code>。<code>StateTable</code>实体由一个客户端应用程序提供,该应用程序有兴趣将<code>State Table</code>中的实体关联<code>Country</code<(<code>countryId=67</code

  • 我想知道在Spring项目中更新JPA实体的最佳实践是什么-更新原始实体还是创建新实体?我看到了这两种方法: 使用原始-在原始实体中实现必要的字段,并将更新后的实体保存回存储库 使用复制-手动创建实体的新实例,将原始实体中的所有字段(更新的字段)设置为新实体,并将实体保存回存储库 您使用/推荐什么方法?为什么呢?

  • 问题内容: 总是有很多与独立实体有关的问题! 首先,它们经常导致hibernate。是的,还有另一个持久性提供程序,它们不抛出异常,但是我认为它们在一致性方面存在一些问题。考虑我们有和实体,从到那里的引用()必须为非null。 我们开始了会话,加载了实例,然后关闭了会话。之后,我们尝试获取对的引用。并假设另一笔交易只是删除了我们和实例。因此,当我们从数据库查询时,我们找不到合适的实例并获取! 因此

  • 问题内容: 问题基本上与下面的问题相同: JPA级联仍然存在,对分离实体的引用将引发PersistentObjectException。为什么? 我正在创建一个引用现有的分离实体的新实体。现在,当我将此实体保存在spring数据存储库中时,会引发异常: 如果我们查看Spring数据JPA的源代码中的save()方法,则会看到: 如果我们看一下isNew() 因此,基本上,如果我保存()一个新实体,

  • 主要内容:JPA实体更新示例JPA允许我们通过更新实体来更改数据库中的记录。 JPA实体更新示例 在这里,我们将演示如何根据主键更新学生的年龄。 完整的项目代码如下所示 - 这个例子包含以下步骤 - 第1步: 在包下创建一个名为的实体类,它包含属性:,和。 文件:StudentEntity.java 的代码如下 - 第2步: 将实体类和其他数据库配置映射到文件中。 文件:persistence.xml 的代码如下 - 在包下