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
}
}
答案 0 :(得分:0)
您的EntityManager
(更好的电话BaseDao
或GenericDao
)的想法很好但需要一些改进。
首先,基础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在没有单行代码的数据库上。