java - JPA事务: select right after commit?

标签 java jpa jboss ejb

我正在将 JBoss EAP 6.1.0 与 EJB/JPA 结合使用。我有一个用户对象,其中包含他所属的多个组,我尝试使用三步方法在数据库中创建它:

  1. 保存用户
  2. 保存他所属的群组
  3. 查询数据库并返回新用户

我的问题是步骤 (3) 总是返回 null,因为提交尚未发生。在步骤 2 和 3 之间添加 em.flush() 没有帮助。我避免对组使用任何 @CASCADE 注释,因此仅保存用户并让组级联不是一种选择。这是示例代码:

@Stateless
public class RegistrationService {

   @EJB
   UserDao userDao;

   public User registerNewUser(User user, List<Group> groups) {
       userDao.saveNewUser(user);
       userDao.saveNewGroupsToUser(user, groups);
       return userDao.findUser(user);
   }
}

这是一个简化的 UserDao:

@Stateless
public class UserDao {

  @PersistenceContext
  private EntityManager em;

  public void saveNewUser(User user) {
    em.persist(user);
  }

  public void saveNewGroupsToUser(User user, List<Group> groups) {
    for (Group group : groups) {
       GroupToUser groupToUser = new GroupToUser(user, group);
       em.persist(groupToUser);
    }

  public User findUser(User user) {
    return em.createQuery("from User where user = :userId")
       .setParameter("userId",user.getUserId())
       .getSingleResult();
  }
}

我发现,如果我使用 @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 注释 findUser(User) 方法,它会按预期工作。这是为什么呢?我认为 registerNewUser() 创建了一个大事务,然后 findUser() 会创建一个嵌套事务,而该事务不应该知道保存情况?

最佳答案

我认为你应该在第 1 步(保存用户之后)之后添加 em.flush(),因为它将执行 SQL 来保存新用户。

第二件事,从代码来看似乎使用了容器管理的事务。 CMT 不允许嵌套事务。因此,基本上添加 REUIRED_NEW 属性可能会强制刷新以前保存的 SQL 查询。确认这一点的一种方法是记录 SQL 查询

关于java - JPA事务: select right after commit?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19106858/

相关文章:

Java加载公钥

java - 垃圾收集和 Apache Commons 元组对

grails - grails依赖报告后如何删除有罪的jar文件

java - Apache Camel、IBM MQ 集成

java - java中如何验证单元格数组是否为空?

java - 如何从 JavaBean(域类)中的属性文件读取值?

java - ORM 使用什么来访问数据库

mysql - 如何从我的 Spring Boot 应用程序在 mysql 中创建新架构

sql - 如何用Oracle触发器通知JBoss

java - Jboss中的spring boot返回错误404