【发布时间】:2015-10-18 05:04:17
【问题描述】:
我正在尝试使用 EntityManager 删除一个对象,一切正常,没有错误,但是当我在数据库中进行一些查询时,对象返回,而不是在数据库中删除。
我的 EntityManager 注入:
public class CdiApplicationConfig {
@Inject
private EntityManagerFactory emf;
@Produces
@ApplicationScoped
public EntityManagerFactory createEntityManagerFactory() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("generalPU");
return emf;
}
public void close(@Disposes EntityManagerFactory emf) {
emf.close();
}
@Produces
@TransactionAttribute // is a bit better than @RequestScoped because it won't allow perform injection outside transaction context
public EntityManager createEntityManager() {
return emf.createEntityManager();
}
public void close(@Disposes EntityManager em) {
if (em.isOpen()) {
em.close();
}
}
}
查看我的删除操作:
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void delete(Bean bean) {
try {
bean = entityManager.merge(bean);
entityManager.remove(bean);
} catch (Exception e) {
e.printStackTrace();
throw new DAOException("Ocorreu um erro ao tentar deletar");
}
}
正如我所说,没有错误,但 BEAN 没有被物理删除。我正在使用 JPA/Hibernate + CDI。
编辑 1:
我解决了这样的应用程序管理事务的问题:
begin();
bean = entityManager.merge(bean);
entityManager.flush();
entityManager.refresh(bean);
commit();
begin() 和 commit() 在哪里使用 EntityManager.getTransaction()
【问题讨论】:
-
试图删除实体的代码不在它应该执行删除操作的事务上下文中。
-
您正在从
EntityManagerFactory获取EntityManager,在这种情况下,您没有使用由EntityManager管理的容器,而@TransactionAttribute将被忽略。使用容器管理的EntityManager。如果由于某些原因它不是一个选项,那么您将不得不手动开始并提交事务(使用UserTransaction或其他)或使用javax.transaction.Transactional使 CDI 托管 bean 成为事务性的。 -
我使用 EJB 作为容器管理,我离开 Spring 使用 CDI。我不明白为什么 TrasactionAttribute 被忽略了。
-
事实上,我发现了问题,但我不知道如何解决。我的应用程序只有 CDI 注释,而 EJB 不理解这个 bean。如何混合 EJB 和 CDI 来使用 Transacional?
-
如果您真的在使用 EJB(您正在混合使用 Spring 和 EJB 之类的东西,我不明白。应该使用它们中的任何一个),那么您编写的代码根本不需要。只需使用
@PersistenceContext注释在EJB 中注入一个容器管理的EntityManager。在 EJB 中总是坚持使用@Inject注解来注入容器管理的EntityManager是一个重大误解(对于容器管理的EntityManager根本不需要)。