java - 更新不需要或不需要 em.persist() 或 em.merge() 吗?

标签 java jpa jakarta-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 ?
    }
}

最佳答案

简而言之:托管实体通常在事务提交时与数据库同步。 JPA 实现负责跟踪更改的托管实体并更新数据库。在您的情况下,调用 user.setNickname(...) 将通知 JPA 该特定用户对象是脏的。默认情况下,事务在调用 session EJB 的业务方法时处于 Activity 状态。

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

更长的故事,引用 JEE 8 子规范(问题是关于 JEE 6,这些仍然适用,尽管在不同的部分编号中):

(JPA 2.1) Section 3.2.4: Synchronization to the Database

The state of persistent entities is synchronized to the database at transaction commit. This synchronization involves writing to the database any updates to persistent entities and their relationships as specified above.

[...]The persistence provider runtime is permitted to perform synchronization to the database at other times as well when a transaction is active and the persistence context is joined to the transaction. The flush method can be used by the application to force synchronization.

本章中还有其他有趣的细节,但请注意,不必必须调用 merge() 才能在末尾保存托管实体。交易。

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

(EJB core 3.2) Section 8.3.6: Specification of a Bean’s Transaction Management Type

By default, a session bean or message-driven bean has container managed transaction demarcation if the transaction management type is not specified. [...]

(EJB core 3.2) Section 8.3.7: Specification of the Transaction Attributes for a Bean’s Methods

The Bean Provider of an enterprise bean with container-managed transaction demarcation may specify the transaction attributes for the enterprise bean’s methods. By default, the value of the transaction attribute for a method of a bean with container-managed transaction demarcation is the REQUIRED transaction attribute, and the transaction attribute does not need to be explicitly specified in this case.

一个重要的细节是实体实际上是受管理的。在本例中,这是因为它们是从 JPA 本身返回的,并且是因为 JPQL 查询 "UserEntity.getAllUsers" 的结构。一般来说,实体可能是非托管的或分离的,在这种情况下,需要调用 merge()persist()

关于java - 更新不需要或不需要 em.persist() 或 em.merge() 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51589284/

相关文章:

java - Web 服务和跨站点请求伪造

session - ColdFusion中J2EE session 管理的缺点

java - Struts2 排除 com.sun :tools:jar:1. 需要 5.0 吗?

java - JSch中如何设置文件类型和文件传输模式?

java - 用 Scanner 读取行

mysql - JPA @NamedQuery 以按位 AND (&) 作为条件

java - 使用 Tomcat 在 Eclipse 中找不到源

java - 如何在Java中获取错误的行号?

java - 模型中的私有(private)成员

java - jpa hibernate @transactional 配置