簡體   English   中英

使用EntityManager時如何處理休眠會話?

[英]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 (更好地稱為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,而無需一行代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM