如何在使用EntityManagers时处理Hibernate会话?

时间:2015-09-30 17:52:31

标签: java hibernate java-ee

Out团队目前正在编写JavaEE Web应用程序,以便在Tomcat应用程序服务器上使用。

我们希望使用Hibernate(5.0.1)处理持久性。为了访问数据库实体,我们使用EntityManagers(不是来自JPA,它们由我们实现,见下文),它们提供了在关联表中列出,创建和删除行的方法。模型类使用Hibernate Annotations进行映射。

我们还有一个静态类PersistenceController,用于初始化Hibernate的SessionFactory并提供一个静态方法来获取新打开的会话。

当然我们希望能够使用单元测试来测试我们的类的功能,所以PersistenceController在我们眼中有点刺。

其他人建议我将所有内容从PersistenceController移到EntityManager基类。他不确定这是否会产生任何副作用。

所以我想“让我们问一下蜂巢的心灵”。在这种情况下,最佳做法是什么?

(如果需要更多代码,我很乐意提供它)

PersistenceController

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

public class PersistenceController {

    private static final SessionFactory sessionFactory;

    static {
        final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                .configure() // configures settings from hibernate.cfg.xml
                .build();
        try {
            sessionFactory = new MetadataSources(registry).buildMetadata()
                    .buildSessionFactory();
        } catch (Exception e) {
            // The registry would be destroyed by the SessionFactory, but we had
            // trouble building the SessionFactory
            // so destroy it manually.
            StandardServiceRegistryBuilder.destroy(registry);
            throw e;
        }
    }

    public static Session openSession() {
        return sessionFactory.openSession();
    }
}

的EntityManager

import java.util.List;

public abstract class EntityManager<T extends PersistenceEntity> {

    public abstract List<T> listAll();

    public abstract void save(T entity);

    public abstract void delete(T entity);

}

ProductManager

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;

import etepat.model.product.Product;

public class ProductManager extends EntityManager<Product> {

    public ProductManager() {
        super();
    }

    @Override
    public List<Product> listAll() {
        try (Session session = PersistenceController.openSession()) {
            Transaction transaction = null;
            try {
                transaction = session.beginTransaction();
                @SuppressWarnings("unchecked")
                List<Product> returned = session.createCriteria(Product.class)
                        .list();
                transaction.commit();
                return returned;
            } catch (Exception e) {
                if (transaction != null) {
                    transaction.rollback();
                }
                e.printStackTrace();
            }
        }
        return new ArrayList<Product>();
    }

    @Override
    public void save(Product entity) {
        // TODO Auto-generated method stub

    }

    @Override
    public void delete(Product entity) {
        // TODO Auto-generated method stub

    }

}

1 个答案:

答案 0 :(得分:0)

您的EntityManager(更好的电话BaseDaoGenericDao)的想法很好但需要一些改进。

首先,基础CRUD方法不必是抽象的。他们可以简单地在泛型T上持久保存/加载/删除/列表。这样你就不必在每个子类上编写这些方法。请参阅此通用dao方法https://github.com/athanasiosem/Hibernate-Generic-Dao-Java/blob/master/src/main/java/com/demien/hibgeneric/dao/GenericDAOImpl.java

其次,您手动管理交易,是否有充分的理由这样做? 使用容器管理的事务(使用注释),您不需要,并通过消除样板try {...} catch {// rollback}来大大简化您的代码。

基本上,对于GenericDao<T>和容器管理的交易,您根本不需要此代码,您的类将GenericDao<ConcreteType>子类化为具体类型,并且他们已准备好进行CRUD在没有单行代码的数据库上。