我想知道在Spring项目中更新JPA实体的最佳做法是什么 - 更新原始实体或创建新实体?我看到这两种方法:如何在Spring JPA中实现实体?实现或创建新的?
- 使用原始 - 在原始实体中实现必要的字段并将此更新的实体保存回存储库。
- 使用副本 - 手动创建实体的新实例,将原始实体(+更新字段)中的所有字段设置为新实体并将实体保存回存储库。
你推荐使用什么方法?为什么?
我想知道在Spring项目中更新JPA实体的最佳做法是什么 - 更新原始实体或创建新实体?我看到这两种方法:如何在Spring JPA中实现实体?实现或创建新的?
你推荐使用什么方法?为什么?
当涉及到更新,标准的方法是将检索实体引用(阅读下面),并进行交易方法中的变化:
private JpaRepository repo;
@Transactional(readOnly = false)
public void performChanges(Integer id){
Entity e = repo.getOne(id);
// alter the entity object
}
关于例如几件事情:
JpaRepository
的getOne
方法,因为它通常比CrudRepository
的findOne
更快。唯一的窍门是你必须确定该实体实际存在于具有给定ID的数据库中。否则,你会得到一个例外。关于findOne
方法不会发生这种情况,所以您需要对每个事务性方法作出决定,这会改变应用程序中的单个实体。EntityManager
上的任何persist
或save
方法,因为更改将在提交事务时自动刷新..并且返回方法。关于你的第二个选择,我不认为这是一个用途,因为你需要使用上述方法获取数据。如果您打算在事务处理之外使用该实体,那么您可以再次使用从上述示例中检索到的实体,然后在事务性上下文中再次执行merge
,并因此继续提供。
获得一个实体,然后只是更新该实体是最简单的方法。由于EntityManager
管理一个实体并且知道被管实体已经存在于DB中(因此不需要执行额外的查询),所以这比创建副本更快。
无论如何,有第三种和最快的方法:使用executeUpdate
对Query
对象。
entityManager
.createQuery("update EntityName set fieldName = :fieldName where id = :id")
.setParameter("fieldName", "test")
.setParameter("id", id)
.executeUpdate();
这是更快,因为绕过持久性上下文
你只需要确保在执行是它自己的事务中,或者它在事务性方法的第一次调用 –