EJB with spring:JPA flush中的事务问题

时间:2014-04-08 06:31:11

标签: spring jpa transactions eclipselink ejb-3.0

我的MessageDriven Bean中注入的EntityManager存在一个问题,它使用spring bean作为服务(引导程序是使用SpringBeanAutowiringInterceptor完成的。

以下是代码:

@MessageDriven(name = "ProcessMDB")
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class ProcessMDB implements MessageListener {

    @Autowired
    private ProcessService processService;

    @Override
    public void onMessage(Message message) {
        try {
            id = message.getLongProperty("ID");
            processService.process(id);
        } catch (Exception e) {
            // Handle error.
        }
    }

进程服务有一个DAO,其中EntityManager注入注释@PersistentContext ...

问题是如果在processService中发生JPA错误,它可能在entityManager.flush()调用期间发生...所以try catch块消失了,并且//句柄错误没有完成。

所以我尝试手动添加同花顺。

@MessageDriven(name = "ProcessMDB")
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class ProcessMDB implements MessageListener {

    @Autowired
    private ProcessService processService;

    @PersistenceContext
    private EntityManager em;

    @Override
    public void onMessage(Message message) {
        try {
            id = message.getLongProperty("ID");
            processService.process(id);
            em.flush();
        } catch (Exception e) {
            // Handle error.
        }
    }

但似乎冲洗没有效果。

我尝试在底层DAO中添加em.flush(例如在persist之后)并且它可以工作!异常提升并执行catch块。但是如果我将em.flush()放在MessageDrivenBean级别,它就不起作用。

我认为这是事务管理器问题... spring bean中的实体管理器与我的ejb中注入的实体管理器不在同一个tx中。

如果我在onMessage()方法中创建em.find,则获取的对象将保留旧值(数据库中的值),而不是服务方法中更改的值。

我已将数据库配置为:

<jee:jndi-lookup id="emf" jndi-name="persistence/PUnit" />

和我的tx经理一样:

<tx:annotation-driven/>

<tx:jta-transaction-manager />

我错了什么?

有人能帮助我吗?

由于

斯特凡

1 个答案:

答案 0 :(得分:0)

您已在EntityManager中注入了ProcessMDB,但该对象仍在ProcessService中保留。

现在,ProcessMDB中的任何操作如何影响ProcessService,两者都有可能他们自己的EntityManager

PersistenceContext的范围与关联EntityManager有关。该对象将在ProcessService&amp;的背景下。不在ProcessMDB中,因此稍后调用flush将不起作用&amp;这是预期的行为。