没有交易的JPA

我是JPA的新手。 我正在开发一个使用JPA(Hibernate实现)和Spring的应用程序。 我在我的persistence.xml中声明了一个持久性单元,并在我的Spring配置文件中配置了关于EntityManagerFactory的配置。 像这样的东西:

        create-drop org.hibernate.dialect.MySQL5Dialect   

然后我有一些DAO,我用@PersistenceContext注释注入entityManager:

 public MyDaoImpl implements MyDao{ private EntityManager entityManager; @PersistenceContext private void setEntityManager(EntityManager em){ this.entityManager = em; } } 

最后,我有一些注入DAO的服务(通过@Autowired Spring的注释):

 public MyServiceImpl implements MyService{ @Autowired private MyDao myDao; public List readOperation(){ // return myDAo.searchAll(); } } 

作为一个只读操作,我认为它不需要@Transactional注释,但没有它,有一个例外:

 java.lang.IllegalStateException: No transactional EntityManager available at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:223) at $Proxy121.unwrap(Unknown Source) 

我读过其他一些post: java.lang.IllegalStateException:没有可用的事务性EntityManager

所有人都说需要交易注释。 它确实适用于它,但我想知道(以及为什么)所有方法(甚至是只读操作)必须是事务性的。

所有方法都需要JPA事务 – 本质上,事务是打开Hibernate会话的事务,您需要一个开放会话来与之交互。

您可以将事务注释为readonly或readwrite,也可以在类级别进行注释以节省对每个方法的注释。 例如:

 @Transactional(readOnly = true) public MyDaoImpl implements MyDao{ private EntityManager entityManager; @PersistenceContext private void setEntityManager(EntityManager em){ this.entityManager = em; } @Transactional(readOnly = false) public void saveItem(MyEntity entity) { } public List searchAll() { } } 

您需要一个事务来处理更改DB中任何内容的所有操作(唯一的例外是SELECT查询,没有锁定)。 检查这个答案 。