是否不需要em.persist()或em.merge()或不进行更新?

时间:2018-07-30 07:51:04

标签: java jpa java-ee ejb java-ee-6

我有下面的代码,想知道JPA如何知道要保持此更新。我期望需要em.merge()来执行更新。这实际上安全吗?

@Stateless
class User { 

    ...

    public void generateRandomNicknames() {
        List<UserEntity> users = em.createNamedQuery("UserEntity.getAllUsers", UserEntity.class)
                                   .getResultList();
        for (UserEntity user : users) {
              user.setNickname(generateRandomNickname());
        }
        // em.merge(user) or em.persist(user) not needed ?
    }
}

1 个答案:

答案 0 :(得分:2)

简而言之: 受管实体通常在事务提交时与数据库同步。 JPA实现负责跟踪更改的 managed 实体并更新数据库。就您而言,调用user.setNickname(...)将通知JPA此特定用户对象已损坏。默认情况下,事务在调用会话EJB的业务方法时处于活动状态。

注意,以上是可以通过配置更改的默认行为!

更悠久的故事,并引用了JEE 8子规范(有关JEE 6的问题,尽管适用于不同的章节号,但它们仍然适用):

  

(JPA 2.1)第3.2.4节:与数据库同步

     

在事务提交时,持久实体的状态将同步到数据库。这种同步   涉及将对持久性实体及其关系的任何更新写入数据库(如指定)   以上。

     

[...]允许持久性提供程序运行时在其他时间与数据库执行同步   以及当事务处于活动状态并且持久性上下文已加入到事务中时。同花顺   应用程序可以使用此方法来强制同步。

本章还有其他有趣的细节,但是请注意,merge()不必不需要调用,以便在事务结束时保存被管理实体。

将我们带入下一个细节,即交易。由于这是会话EJB的一种方法,因此默认情况下,它在事务的上下文中运行:

  

(EJB核心3.2)第8.3.6节:Bean事务管理类型的规范

     

默认情况下,如果未指定事务管理类型,则会话Bean或消息驱动的Bean具有容器管理的事务划分。 [...]

     

(EJB核心3.2)第8.3.7节:Bean方法的事务属性规范

     

具有容器管理的事务划分的企业Bean的Bean Provider可以为企业Bean的方法指定事务属性。默认情况下,具有容器管理的事务划分的Bean方法的事务属性的值是REQUIRED事务属性,在这种情况下不需要显式指定事务属性。

一个重要的细节是实体是实际管理的。在这种情况下,这是因为它们是从JPA本身返回的,并且是因为JPQL查询"UserEntity.getAllUsers"的结构如何。通常,实体可能不受管理或分离,在这种情况下,必须调用merge()persist()