我正在使用 Struts 1.3 + JPA(使用 Hibernate 作为持久性提供者)开发一个简单的“书店”项目。我不能切换到 Spring 或任何其他更复杂的开发环境(例如,Jboss),也不能使用任何特定于 Hibernate 的技术(例如,Session
类)。
鉴于我在 JSE 环境中,我需要明确管理整个 EntityManager 的生命周期。
Book
实体定义如下:
@Entity
public class Book {
@Id private String isbn;
private String title;
private Date publishDate;
// Getters and Setters
}
我定义了三个Action
类,它们分别负责检索所有书籍实例、通过 ISBN 检索单个书籍实例以及将分离的书籍合并到数据库中。
为了增加业务逻辑代码和数据访问代码之间的关注点分离,我引入了一个简单的BookDAO
对象,它负责执行 CRUD 操作。理想情况下,所有与数据访问相关的调用都应该委托给持久层。例如,ListBookAction
定义如下:
public class ListBookAction extends Action {
private BookDAO dao = new BookDAO();
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// Retrieve all the books
List<Book> books = dao.findAll();
// Save the result set
request.setAttribute("books", books);
// Forward to the view
return mapping.findForward("booklist");
}
}
BookDAO 对象需要访问一个EntityManager
实例才能执行任何操作。鉴于这EntityManger
不是线程安全的,我引入了一个名为的帮助类BookUnitSession
,它将 EntityManager 封装在一个ThreadLocal
变量中:
public class BookUnitSession {
private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("BookStoreUnit");
private static final ThreadLocal<EntityManager> tl = new ThreadLocal<EntityManager>();
public static EntityManager getEntityManager() {
EntityManager em = tl.get();
if (em == null) {
em = emf.createEntityManager();
tl.set(em);
}
return em;
}
}
一切似乎都有效,但我仍然有些担心。即:
- 这个解决方案是最好的吗?在这种情况下,最佳做法是什么?
- 我仍然需要明确关闭 EntityManager 和 EntityManagerFactory。我怎样才能做到这一点?
谢谢