我正在学习Java中的持久性。
我使用的是Java EE 7和Payara服务器。
我注意到每种方法都使用不同的持久性方法。
示例:
-
简单
@Stateless public class BookServiceBean implements BookService { @PersistenceContext private EntityManager em; public void createOrUpdate(Book book) { em.persist(book); } public void remove(Book book) { em.remove(book); } }
-
对于
flush()
,这是在persistene.xml中验证策略未设置为"AUTO"时使用的,对吗?@Stateless public class BookServiceBean implements BookService { @PersistenceContext private EntityManager em; public void createOrUpdate(Book book) { em.persist(book); em.flush(); } public void remove(Book book) { em.remove(book); em.flush(); } }
-
带有交易
@Stateless public class BookServiceBean implements BookService { @PersistenceContext private EntityManager em; public void createOrUpdate(Book book) { utx.begin(); em.persist(book); utx.commit(); } public void remove(Book book) { utx.begin(); em.remove(book); utx.commit(); } }
我什么时候以及为什么必须使用最后一个?
是否有必要在每种方法的末尾使用em.close()
?
有哪些良好做法?
第一个方法是一个没有所有手动刷新和事务模糊的EJB方法,它是规范方法。默认情况下,单个EJB方法调用已经算作单个完整事务。EJB容器将在调用方法之前透明地开始事务,并在方法返回时提交事务(或在从方法抛出应用程序异常时回滚)。
第二个例子中的手动冲洗是不必要的。通常,只有在修改实体(即使其"脏")时,才希望使用em.flush()
,然后(间接)在同一事务中对其执行SELECT
。这是罕见的,但在现实世界中也有它的用例,通常是当你想SELECT
一个脏实体是其子级的父级时。
第三个例子中的手动事务管理是完全没有必要的。读过第一段之后,你应该已经意识到了这一点。只有当您不使用JTA
,而是使用RESOURCE_LOCAL
(通常在Java SE中,而不是Java EE中)时,才需要手动事务管理。
另请参阅:
- 什么时候有必要或方便使用Spring或EJB3或将它们一起使用
- JSF请求范围的bean不断在每个请求上重新创建新的Stateful会话bean
- Java EE前端方法中服务层异常的处理