[英]How to handle multiple Entitymanagers via OpenEntityManagerInViewFilter on Spring
[英]How to handle Hibernate Sessions when using EntityManagers?
目前,Out團隊正在對JavaEE Web應用程序進行編程,以在Tomcat應用服務器上使用。
我們想使用Hibernate(5.0.1)處理持久性。 要訪問數據庫實體,我們使用EntityManagers
(不是JPA的,它們是由我們實現的,請參見下文),該實體提供了列出,創建和刪除關聯表中的行的方法。 模型類使用Hibernate Annotations進行映射。
我們還有一個靜態類PersistenceController
,它初始化Hibernate的SessionFactory
並提供一個靜態方法來獲取新打開的會話。
當然,我們希望能夠使用單元測試來測試類的功能,因此PersistenceController
在我們眼中有點棘手。
有人建議我將所有內容從PersistenceController
移到EntityManager
基類。 他不確定這是否會帶來任何副作用。
所以我想“讓我們問一下蜂巢的想法”。 在這種情況下,最佳做法是什么?
(如果需要更多代碼,我很樂意提供)
持久性控制器
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();
}
}
實體管理器
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);
}
產品經理
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
}
}
您的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,而無需一行代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.