1

我正在使用 JBoss 7.1.1 Final、Weld、Hibernate 4、Seam 3 进行开发,但我不明白以下行为。我使用Seam Managed Persistence Context for Entity manager and Persistence Interceptor from Seam 3。我有以下CDI Bean:

 @ViewScoped
 @Named
 public class RegistrationController implements Serializable {

    @Inject
    private RegisterService service;

    @Inject
    private EntityManager em;

    public void register() {
          Person p = service.register("username","password");
          Person pp = em.find(Person.class, p.getId()); //returns null
    } 
 }

并遵循 EJB

 @Stateless
 @Local(IRegisterService.class)
 public RegisterService implements IRegisterService {

      @Inject
      private EntityManager em;      

      @Override
      @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
      public Person register(String username, String password) {
           return em.merge(new Person(username, password));
      }
 }

因此,由于我使用 Seam Persistence 模块,我假设会发生这种操作流程:

1) 从前端调用registrationController.register()

2) 发起新事务A

3) service.register(...) 被调用

4)事务A被挂起,事务B被创建用于执行service.register(因为它被REQUIRES_NEW注解)

5) 执行 service.register(...) 完成

6) 事务 B 被提交

7) 由于我使用 COMMIT 刷新类型,因此会调用刷新

8) 交易 A 被打开

现在, em.find(Person.class, p.getId()) 正试图找到刚刚坚持的人。由于事务 B 已提交并且实体管理器已刷新,它应该会找到它。但它返回null。如果我手动冲洗,那么它可以工作。

我在哪里犯错?是不是有些误会?

4

1 回答 1

0

通过查看您的代码,我会说 - 因为RegistrationController它是一个普通的托管 bean - 它不会启动自己的事务。这基本上意味着您有一个事务 B。

于 2012-08-14T04:14:49.973 回答