没有交易的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查询,没有锁定)。 检查这个答案 。