事务提交后更新查询未刷新

时间:2017-07-17 09:41:13

标签: java hibernate jpa ejb ejb-3.0

我有几个扩展BaseRepository的存储库,如下所示:

public abstract class IsoRepository<T extends Serializable> {
    @PersistenceContext
    protected EntityManager entityManager;

    public void persist(T obj) {
        entityManager.persist(obj);
    }
}

@Stateless
public class T1Repository extends BaseRepository<T1> {
    // methods depending on repository
}

@Stateless
public class T2Repository extends BaseRepository<T2> {
    public Optional<T2> findByOrderId(String id) {
        return entityManager.createNamedQuery(/* ... */, T2.class)
            .setParameter("id", id).getResultList().stream().findFirst();
    }
}

// and others

EJB bean包含用于保存事务的方法:

@Stateless
public class TransactionService {
    @EJB
    private T2Repository t2Repository;

    public void saveTransaction() {
        // Here occurs logic that saves new entities to database via repositories injected with EJB annotation
        // and also as the last operation update is performed:
        T2 t2 = t2Repository.findById(id);
        t2.setProperty(someProperty);
        t2Repository.persist(t2);
    }
}

问题是所有插入查询都保存在数据库中,但不是这个更新不好。我发现我需要明确地调用entityManager.flush(),因为它似乎解决了这个问题,但我真的不明白为什么会发生这种情况。我一直认为在提交事务后,所有数据都会自动刷新。我是否在配置中做了哪些更改?

1 个答案:

答案 0 :(得分:1)

根据JPA-Documentation

"persist(Object entity)
Make an instance managed and persistent." 

表示,persist只能用于插入。通常你应该得到

"EntityExistsException - if the entity already exists. 
(If the entity already exists, the EntityExistsException may be 
thrown when the persist operation is invoked, or the 
EntityExistsException or another PersistenceException may be thrown at 
flush or commit time.)"

正如文件所述。所以:

    T2 t2 = t2Repository.findById(id);
    t2.setProperty(someProperty);
    t2Repository.persist(t2);

根据JPA定义,无论如何都应该导致EntityExistsException,立即或在事务结束时。这一端也可以在方法的末尾,该方法本身调用TransactionService.persist。 此异常应导致任何情况下的回滚,因此您的更新将永远不会完成。

我的建议:

删除持久调用,因为在查找期间对象变为受管理,更改将在事务结束时完成。

请参阅:does-jpa-hibernate-save-even-when-not-calling-persist