Hibernate Static Method For Entity Operations

时间:2016-06-18 20:08:09

标签: spring hibernate

I am building a web application using Struts2 and hibernate, along with Spring for dependency injection into the action classes. I am trying to determine if static methods for selecting, updating, and inserting into the database are a good move. If a utility class was to be used it would contain static methods that would act as wrappers for hibernate sessions similar to the following.

First Option - Static Methods

public static <T> T getEntity(Serializable id, Class<?> klass) {
    Transaction txn = null;
    Session session = getSessionFactory().getCurrentSession();
    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. Message: {}", id, e.getMessage());
    } finally {

    }
    return entity;
}

public static void updateEntity(Object entity) {
    Transaction txn = null;
    Session session = getSessionFactory().getCurrentSession();
    try {
        txn = session.beginTransaction();
        session.update(entity);
        txn.commit();
    } catch (HibernateException e) {
        log.debug("Object {} could not be updates.", entity);
    } finally {

    }
}

An interceptor would be used to open and close the hibernate session on each request.

public class HibernateInterceptor extends MethodFilterInterceptor {

@Override
protected String doIntercept(ActionInvocation invocation) throws    Exception {
        JPAManager.getSessionFactory().openSession();
        String result = invocation.invoke();
        JPAManager.getSessionFactory().getCurrentSession().close();
        return result;
    }
}

The static methods of the utility class should be thread safe because each object that is passed to the methods is local to the thread and hibernate sessions are thread safe as well. If I were using a session variable however that would be a problem but that's not an issue local to just static methods. The downside to using static methods though is they cannot be overridden by a future implementation and are thus concrete in their functionality. In addition, this might encourage lazy design practices where it's just too easy to call the static methods leading to all kinds of dependencies across the layers.

2nd Option - Instance Methods

The methods of the JPAManager class would no longer be static and an instance of the class would be injected into the Action classes via spring. Future implementations could override the functionality by extending the class or I could write it as an abstract class and provide the implementation class to Spring for injection. I like this approach better for scalability and long term maintenance. The hibernate entities could be passed into a Business Delegate class, perform the operations and before returning the action result, the instance of JPAManager updates the object, etc.

public String execute(){
    //perform business logic on entityObject
    this.jpaManager.updateEntity(entityObject);
    return "success";
}

public JPAManager getJpaManager() {
    return this.jpaManager;
}

public void setJpaManager(JPAManager manager) {
    this.jpaManager = manager;
}

I would like to know which option is best as this is my first time implementing all three frameworks into one solution.

1 个答案:

答案 0 :(得分:2)

你也应该考虑回滚。

catch (HibernateException e) - 此处仅使用HibernateException不正确。

  

hibernate会话是线程安全的

这不是一个正确的陈述。

一些值得学习的方法

Currently recommended usage patterns for Hibernate

HibernateTemplate and HibernateDaoSupport

Spring Generic DAO And Generic Service Implementation

Spring Data JPA Tutorial

The open session In View Anti-Pattern

如果你想要一个例子,如何实施像你这样的自行车,你可以参考my library