Hibernate在RESTful Web服务中高效使用会话

时间:2016-05-31 17:27:22

标签: java hibernate jersey-2.0

我目前正在创建一个使用hibernate和mysql公开数据的平台RESTful Web服务。在创建服务时,我遇到了几个关于正确使用Hibernate会话的问题。

我创建了SessionFactory的单例,用于检索新会话。

public class JPAServletContextListener implements ServletContextListener {

private static final Logger log = LoggerFactory.getLogger(JPAServletContextListener.class);

/**
 * Initialize the JPAManager.
 */
public void contextInitialized(ServletContextEvent sce) {
    JPAManager.initializeJPAManager();
    log.info("JPAManager initialized.");

}

public void contextDestroyed(ServletContextEvent sce) {
    JPAManager.closeJPAManager();
    log.info("JPAManager destroyed successfully.");
}

}

private static SessionFactory sessionFactory;

public static void initializeJPAManager() {
    Configuration config = new Configuration();
    config.configure("hibernate.cfg.xml");
    sessionFactory = config.buildSessionFactory();
}

目前,只要需要一个对象,就会打开会话,检索实体,然后关闭会话。

public static <T> T getEntity(Serializable id, Class<?> klass) {
    Transaction txn = null;
    Session session = getSessionFactory().openSession();
    T entity = null;
    try {
        txn = session.beginTransaction();
        entity = (T) session.get(klass, id);
        if (entity == null) {
            throw new NullPointerException(String.format("row {} could not be found in the database.", id));
        }
        txn.commit();
    } catch (HibernateException e) {
        log.debug("Exception encountered while retrieving {} from the database.", id, e);
    } finally {
        session.close();
    }
    return entity;
}

我正在使用Bean Validation API在数据库中的任何信息更新之前验证进入服务的数据。 Bean验证将服务的传入值与数据库值进行比较,以确保例如不将不正确的货币添加到现有订单。每个bean验证都是从数据库中获取一个订单实体,所以如果我在POJO上有10个bean验证,我会看到10个单独的会话开放,检索实体,并通过getEntity()方法关闭会话。由于服务规模可能会有问题。

更简单的方法是在Jersey请求过滤器中打开hibernate会话,在请求期间保持打开状态,然后在响应过滤器中关闭它?可以通过jboss documentation中列出的getCurrentSession()检索特定于请求的会话。我会对服务中的数据完整性感到担忧,但性能提升可能会保证这种设计,并且它基于hibernate文档对每个请求的会话设计模式似乎是有效的。

0 个答案:

没有答案