【问题标题】:Can we use JPA outsite EJB container?我们可以使用 JPA 外部 EJB 容器吗?
【发布时间】:2014-11-21 09:22:08
【问题描述】:

我的应用程序在 Jboss 4.0.5 GA 上运行,需要升级才能在 jboss 7.1.1 final 上运行。 JSF 页面中的一切,业务逻辑都解决了。但我们面临的关键问题是:在 jboss4 的旧应用程序中,我们不使用 JPA,我们直接使用休眠会话。并通过threadlocal管理休眠会话。我们应用了 3 层应用程序:[UI 后端 bean] 调用 [EJB 执行业务] 调用 [DAO 对象通过休眠会话获取和更新数据库]。
这个设计被打破了,现在!因为我们找不到像休眠会话一样在线程本地管理实体管理器的方法。可能我是个糟糕的开发人员。
请帮助我,我们可以使用 jpa 外部 EJB。我想要一个名为 DAOUtil 的静态类来管理和获取实体管理器,还可以执行保存或更新数据。任何人都告诉我如何做到这一点。数据源(xa-datasource)怎么样,persistent.xml怎么样?
这是访问数据库的类:

package com.esilicon.dao.hibernate;

import java.io.Serializable;
import java.sql.Connection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Example;
import org.hibernate.engine.spi.SessionImplementor;

public class HibernateDAOSession extends DAOSession {


    /**
     * @associates Class
     */
    private static HashMap implementations = new HashMap();
    private Session hibernateSession;
    // private Transaction tx;
    private boolean JTAEnvironment;
    private EntityManager em;

    public HibernateDAOSession(Session s, boolean jta) {
        this.hibernateSession = s;
        this.JTAEnvironment = false;
    }

    public HibernateDAOSession(Session s, boolean jta, EntityManager em) {
        this.hibernateSession = s;
        this.JTAEnvironment = false;
        this.em = em;
    }

    public BaseDAO getDAO(Class clazz) {
        try {
            Class impl = getImplementationClass(clazz);
            HibernateDAO dao = (HibernateDAO) impl.newInstance();
            // dao.setCurrentSession(this.getHibernateSession());
            // session will be provided by DAOUtil from a threadlocal variable.
            return dao;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private Class getImplementationClass(Class clazz) throws ClassNotFoundException {
        Class impl = (Class) implementations.get(clazz);
        if (impl == null) {
            String name = clazz.getName();
            String packageName = clazz.getPackage().getName();
            String className = name.substring(packageName.length() + 1);
            StringBuffer implClassName = new StringBuffer(packageName).append(".hibernate.").append(className).append("DAO");
            impl = Class.forName(implClassName.toString());
            implementations.put(clazz, impl);
        }
        return impl;
    }

    public void close() {
        if (this.JTAEnvironment)
            return;
        try {
            Session s = this.getHibernateSession();
            if (s != null && s.isOpen() && this.getEm() != null) {
                s.close();
                this.setHibernateSession(null);
                /*
                 * this.getEm().clear(); this.getEm().close();
                 */
                this.setEm(null);
            }

            /*if (s != null && s.isOpen()) {

            }*/

        } catch (HibernateException e) {
            e.printStackTrace();
            throw new HibernateDAOException(e);
        }

    }

    public void beginTransaction() {
        try {
            /*if (getHibernateSession().getTransaction() == null) {
                this.getHibernateSession().beginTransaction();
            } else if (!getHibernateSession().getTransaction().isActive() || getHibernateSession().getTransaction().wasCommitted()) {
                getHibernateSession().getTransaction().begin();
            }*/
            //return getHibernateSession().getTransaction();
        } catch (HibernateException e) {
            e.printStackTrace();
            throw new HibernateDAOException(e);
        }
    }

    public void commit() {
        //this.getHibernateSession().flush();
        /*if (this.JTAEnvironment)
            return;
        try {
            if (getHibernateSession().getTransaction() != null && getHibernateSession().getTransaction().isActive()) {
                getHibernateSession().getTransaction().commit();
            }
        } catch (HibernateException e) {
            e.printStackTrace();
            rollback();
            throw new HibernateDAOException(e);
        }*/
    }

    public void rollback() {
        // TODO: should we allow rolback on session in JTAEnvironment ?
        /*try {
            if (getHibernateSession().getTransaction() != null && getHibernateSession().getTransaction().isActive()) {
                getHibernateSession().getTransaction().rollback();
            }
        } finally {
            // close();
            DAOUtil.closeEntityManager();
        }*/
    }

    public Transaction getCurrentTransaction() {
        return getHibernateSession().getTransaction();
    }

    private Query prepareQuery(Query q, int start, int count, Map params) {
        String[] namedParams = q.getNamedParameters();
        if (namedParams.length > 0 && params != null) {
            for (int i = 0; i < namedParams.length; i++) {
                if (params.get(namedParams[i]) instanceof java.util.List) {
                    q.setParameterList(namedParams[i], (List) params.get(namedParams[i]));
                } else {
                    q.setParameter(namedParams[i], params.get(namedParams[i]));
                }
            }
        }
        if (start >= 0)
            q.setFirstResult(start);
        if (count >= 0)
            q.setMaxResults(count);
        return q;
    }

    public Session getHibernateSession() {
        return hibernateSession;
    }

    public void setHibernateSession(Session hibernateSession) {
        this.hibernateSession = hibernateSession;
    }

    public Object update(Object o) {
        try {
            this.getHibernateSession().update(o);
            return o;
        } catch (HibernateException e) {
            e.printStackTrace();
            throw new HibernateDAOException(e);
        }

    }

    public boolean isJTAEnvironment() {
        return JTAEnvironment;
    }

    public Object save(Object o) {
        try {
            this.getHibernateSession().save(o);
            return o;
        } catch (HibernateException e) {
            e.printStackTrace();
            throw new HibernateDAOException(e);
        }
    }

    public Object saveOrUpdate(Object o) {
        try {
            this.getHibernateSession().saveOrUpdate(o);
            return o;
        } catch (HibernateException e) {
            e.printStackTrace();
            throw new HibernateDAOException(e);
        }

    }

    public void flush() {
        try {
            this.getHibernateSession().flush();
        } catch (HibernateException e) {
            e.printStackTrace();
            throw new HibernateDAOException(e);
        }
    }

    public Object refresh(Object o) {
        try {
            this.getHibernateSession().refresh(o);
            return o;
        } catch (HibernateException e) {
            e.printStackTrace();
            throw new HibernateDAOException(e);
        }
    }

    public void evict(Object o) {
        try {
            this.getHibernateSession().evict(o);
        } catch (HibernateException e) {
            e.printStackTrace();
            throw new HibernateDAOException(e);
        }
    }

    public Object query(String query, Map map, boolean uniqueResult) {
        try {
            Query q = this.getHibernateSession().createQuery(query);
            prepareParameters(q, map);
            if (uniqueResult) {
                return q.uniqueResult();
            } else {
                return q.list();
            }
        } catch (HibernateException e) {
            e.printStackTrace();
            throw new HibernateDAOException(e);
        }
    }

    private void prepareParameters(Query q, Map map) {
        if (map == null)
            return;
        String[] params = q.getNamedParameters();
        for (int i = 0; i < params.length; i++) {
            if (map.get(params[i]) instanceof java.util.List) {
                q.setParameterList(params[i], (List) map.get(params[i]));
            } else {
                q.setParameter(params[i], map.get(params[i]));
            }
        }
    }

    public Connection getConnection() {
        SessionImplementor si = (SessionImplementor) getHibernateSession();
        //this.connection = si.connection();
        return si.connection();
    }

    public void delete(Object o) {
        try {
            this.getHibernateSession().delete(o);
        } catch (HibernateException e) {
            e.printStackTrace();
            throw new HibernateDAOException(e);
        }

    }

    public Object findUniqueEntityByID(Class entityClass, Serializable id) {
        try {
            return this.getHibernateSession().get(entityClass, id);
        } catch (HibernateException e) {
            e.printStackTrace();
            throw new HibernateDAOException(e);
        }
    }

    public int executeUpdate(String query, Map params) {
        try {
            Query q = this.getHibernateSession().createQuery(query);
            prepareParameters(q, params);
            return q.executeUpdate();
        } catch (HibernateException e) {
            e.printStackTrace();
            throw new HibernateDAOException(e);
        }
    }

    public Object nativeQuery(String query, Map map, boolean uniqueResult) {
        try {
            Query q = this.getHibernateSession().createSQLQuery(query);
            prepareParameters(q, map);
            if (uniqueResult) {
                return q.uniqueResult();
            } else {
                return q.list();
            }
        } catch (HibernateException e) {
            e.printStackTrace();
            throw new HibernateDAOException(e);
        }
    }

    public int executeNativeUpdate(String query, Map params) {
        try {
            Query q = this.getHibernateSession().createSQLQuery(query);
            prepareParameters(q, params);
            return q.executeUpdate();
        } catch (HibernateException e) {
            e.printStackTrace();
            throw new HibernateDAOException(e);
        }
    }

    public EntityManager getEm() {
        return em;
    }

    public void setEm(EntityManager em) {
        this.em = em;
    }

    @Override
    public Query createQuery(String hqlQuery) {
        return getHibernateSession().createQuery(hqlQuery);
    }

    @Override
    public SQLQuery createSQLQuery(String nativeQuery) {
        // TODO Auto-generated method stub
        return getHibernateSession().createSQLQuery(nativeQuery);
    }

    @Override
    public void disconnect() {
        // TODO Auto-generated method stub
        getHibernateSession().disconnect();
    }

    @Override
    public Object get(Class<?> clazz, Serializable id) {
        // TODO Auto-generated method stub
        return getHibernateSession().get(clazz, id);
    }

    @Override
    public Object load(Class<?> clazz, Serializable id) {
        // TODO Auto-generated method stub
        return getHibernateSession().load(clazz, id);
    }

    @Override
    public Object merge(Object o) {
        // TODO Auto-generated method stub
        return getHibernateSession().merge(o);
    }

    @Override
    public Query getNamedQuery(String nameQuery) {
        // TODO Auto-generated method stub
        return getHibernateSession().getNamedQuery(nameQuery);
    }
}

管理 HibernateSessionDAO 的类

package com.esilicon.dao;

import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;

import javax.naming.InitialContext;
import javax.sql.DataSource;

import org.hibernate.Session;
import org.hibernate.proxy.HibernateProxy;

import com.esilicon.dao.hibernate.HibernateDAOSession;
import com.esilicon.util.logging.Logger;

public class DAOUtil {
    public static final String PERSISTENT_UNIT = "vms4_jboss7";

    static ThreadLocal<DAOSession> threadLocalDAOEntityManager = new ThreadLocal<DAOSession>();
    static Logger logger = Logger.getLogger(DAOUtil.class.getName());

    public static DAOSession openEntityManager(DAOEntityManagerFactory factory) {
        DAOSession entityManager = (DAOSession) threadLocalDAOEntityManager.get();
        if (entityManager != null && entityManager.isOpen()) {
            return entityManager;
        }
        try {
            entityManager = factory.getEntityManager();
        } catch (Exception e) {
            // e.printStackTrace();
            entityManager = factory.openEntityManager();
        }
        threadLocalDAOEntityManager.set(entityManager);
        return entityManager;
    }

    public static DAOSession openSession(DAOSessionFactory factory) {

        DAOSession daoSession = (DAOSession) threadLocalDAOEntityManager.get();
        if (daoSession != null && daoSession.isOpen()) {
            return daoSession;
        }
        try {
            threadLocalDAOEntityManager.remove();
            daoSession = factory.getSession();
        } catch (Exception e) {
            e.printStackTrace();
            daoSession = factory.openSession();
        }
        threadLocalDAOEntityManager.set(daoSession);
        return daoSession;
    }

    public static DAOSession openSession(DAOEntityManagerFactory factory) {

        return openEntityManager(factory);
    }

    public static DAOSession getEntityManager() {
        DAOSession entityManager = (DAOSession) threadLocalDAOEntityManager.get();
        if (entityManager == null || !entityManager.isOpen()) {
            entityManager = DAOUtil.openEntityManager(DAOEntityManagerFactory.getInstance(null));
        }
        return entityManager;
    }

    public static DAOSession getSession() {
        return getEntityManager();
    }

    public static void closeEntityManager() {
        DAOSession entityManager = (DAOSession) threadLocalDAOEntityManager.get();
        if (entityManager != null) {
            entityManager.close();
            logger.debug("EntityManager Closed for Thread " + Thread.currentThread().getName());
            threadLocalDAOEntityManager.remove();
        }
    }

    public static void closeSession() {
        closeEntityManager();
    }

    public static void beginTransaction() {
        DAOSession entityManager = (DAOSession) threadLocalDAOEntityManager.get();
        logger.debug("--- BeginTransaction --- Thread " + Thread.currentThread().getName());
        if (entityManager == null) {
            entityManager = openEntityManager(DAOEntityManagerFactory.getInstance(null));
        }
        entityManager.beginTransaction();
    }

    public static void commitTransaction() {
        DAOSession entityManager = (DAOSession) threadLocalDAOEntityManager.get();
        logger.debug("--- CommitTransaction --- Thread " + Thread.currentThread().getName());
        entityManager.commit();
    }

    public static void rollbackTransaction() {
        DAOSession entityManager = (DAOSession) threadLocalDAOEntityManager.get();
        if (entityManager != null && entityManager.isOpen()) {
            entityManager.rollback();
        }
    }

    public static BaseDAO getDAO(Class clazz) {
        return getEntityManager().getDAO(clazz);
    }

    public static Object narrow(Object proxy) {

        try {
            return ((HibernateProxy) proxy).getHibernateLazyInitializer().getImplementation();
        } catch (Exception e) {
            return proxy; // not a proxy
        }

    }

    public static void closeConnection(Connection con) {
        try {
            if (con != null && !con.isClosed()) {
                con.close();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static Connection getNonXAConnection() {
        try {
            InitialContext context = new InitialContext();
            DataSource dataSource = (DataSource) context.lookup(JNDILookup.PURE_CONNECTION_JNDI);
            return dataSource.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
            logger.fatal(e.getMessage(), e.getCause());
        }
        return null;
    }
}

【问题讨论】:

  • 您如何管理您的交易?使用 UserTransaction 或 EntityManager 的交易?您使用本地线程解决了什么问题?您是否使用它在 servlet 过滤器中初始化事务 + EntityManager?
  • 你可以看到,我有 EntityManager 的对象,但我不能使用它,因为与托管事务有关的错误。我必须通过解开休眠会话来解决。通过我的实现,如何使用 EntityManager 代替 HibernateSession?
  • 您似乎正在使用 entitymanager 管理事务。尝试从 persistence.xml 禁用容器管理的事务。有关如何配置持久性单元以使用 RESOURCE_LOCAL 事务的信息,请参阅tomee.apache.org/jpa-concepts.html

标签: java hibernate jakarta-ee jpa jboss7.x


【解决方案1】:

使用依赖注入将实体管理器注入到你的 dao 类中:

例如:

@PersistenceContext
private EntityManager entityManager;

【讨论】:

  • DAO 类不是 EJB,只是一个纯 java 类。但是,如果我可以注入实体管理器,我想我无法手动执行保存/更新。
  • 无论如何都需要管理 DAO 类。你如何创建一个新实例?只需将类标记为:@Singleton(name = "myDaoObject")。如果您想编写自定义 sql 语句,实体管理器具有持久、删除、查找等方法或 createQuery。
  • 我是 DAO 的核心,我有一个名为 HibernateSessionDAO 的对象,它由 theadlocal 管理。我使用的情况下,我从 threadlocal 获取这个对象。此对象具有 EntityManager 的属性,但我无法坚持不出错:原因:java.sql.SQLException: Connection is not associated with a managed connection.org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6@22b4e311 at org. jboss.jca.adapters.jdbc.WrappedConnection.lock(WrappedConnection.java:154) at org.jboss.jca.adapters.jdbc.WrappedConnection.prepareStatement(WrappedConnection.java:394)
  • 如果您要在其中注入实体管理器,请不要将您的 dao 类设为单例! EntityManager 不是线程安全的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-27
  • 1970-01-01
  • 2017-10-30
  • 2017-09-29
  • 1970-01-01
  • 1970-01-01
  • 2020-03-24
相关资源
最近更新 更多