Hibernate不会关闭DB上的连接/会话

时间:2017-09-15 03:09:45

标签: java oracle hibernate jpa

我在使用Hibernate时遇到了问题。每次我调用一个对数据库执行查询或更新的方法时,hibernate都会在数据库中打开一个会话,然后不会关闭。我已经尝试了所有的东西,但实际上每次都叫做em.getTransaction.begin();它在Oracle bd中创建一个会话,不再关闭。

以下是我的代码(persistence.xml,GenericDAO等)的详细信息

<persistence version="2.0"
             xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">


    <persistence-unit name="FilaTrello" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <class>integration.wcc.model.Chamado</class>

        <properties>
            <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@//10.ip.aqui/xxxint.xxx.com.br"/>
            <property name="javax.persistence.jdbc.user" value="x_SUPORTE"/>
            <property name="javax.persistence.jdbc.password" value="x_SUPORTE"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9iDialect"/>
            <property name="hibernate.connection.shutdown" value="true"/>
            <!-- <property name="hibernate.hbm2ddl.auto" value="none"/> -->
            <property name="hibernate.synonyms" value="true"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="false"/>
          </properties>

    </persistence-unit>
</persistence>

GenericDAO:

package integration.wcc.dao;

import javax.persistence.*;
import javax.persistence.criteria.CriteriaQuery;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
abstract class GenericDAO<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("FilaTrello");
    private EntityManager em = emf.createEntityManager();;


    private Class<T> entityClass;

    public void beginTransaction() {
            em.clear();
            em.getTransaction().begin();

    }

    public void commit() {
        em.getTransaction().commit();
    }

    public void rollback() {
        em.getTransaction().rollback();
    }

    public void closeTransaction() {
       em.close();
    }

    public void commitAndCloseTransaction() {
        commit();
        closeTransaction();
    }

    public void flush() {
        em.flush();
    }

    public void joinTransaction() {
        em = emf.createEntityManager();
        em.joinTransaction();
    }

    public GenericDAO(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    public void save(T entity) {
        em.persist(entity);

    }

    public void delete(Object id, Class<T> classe) {
        T entityToBeRemoved = em.getReference(classe, id);

        em.remove(entityToBeRemoved);
    }

    public T update(T entity) {
        return em.merge(entity);
    }

    public T find(int entityID) {
        return em.find(entityClass, entityID);
    }

    public T findL(Long entityID) {
        return em.find(entityClass, entityID);
    }

    public T findReferenceOnly(int entityID) {
        return em.getReference(entityClass, entityID);
    }

    // Using the unchecked because JPA does not have a
    // em.getCriteriaBuilder().createQuery()<T> method
    @SuppressWarnings({"unchecked", "rawtypes"})
    public List<T> findAll() {
        CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return em.createQuery(cq).getResultList();
    }

    // Using the unchecked because JPA does not have a
    // query.getSingleResult()<T> method
    @SuppressWarnings("unchecked")
    protected T findOneResult(String namedQuery, Map<String, Object> parameters) {
        T result = null;

        try {
            Query query = em.createNamedQuery(namedQuery);

            // Method that will populate parameters if they are passed not null and empty
            if (parameters != null && !parameters.isEmpty()) {
                populateQueryParameters(query, parameters);
            }

            result = (T) query.getSingleResult();

        } catch (NoResultException e) {
            System.out.println("No result found for named query: " + namedQuery);
        } catch (Exception e) {
            System.out.println("Error while running query: " + e.getMessage());
            e.printStackTrace();
        }

        return result;
    }

    @SuppressWarnings("unchecked")
    protected List<T> findListResult(String namedQuery, Map<String, Object> parameters) {
        List<T> result = null;

        try {
            Query query = em.createNamedQuery(namedQuery);

            // Method that will populate parameters if they are passed not null and empty
            if (parameters != null && !parameters.isEmpty()) {
                populateQueryParameters(query, parameters);
            }

            //result = (T) query.getSingleResult();
            result = (List<T>) query.getResultList();

        } catch (NoResultException e) {
            System.out.println("No result found for named query: " + namedQuery);
        } catch (Exception e) {
            System.out.println("Error while running query: " + e.getMessage());
            e.printStackTrace();
        }

        return result;
    }


    private void populateQueryParameters(Query query, Map<String, Object> parameters) {
        for (Map.Entry<String, Object> entry : parameters.entrySet()) {
            query.setParameter(entry.getKey(), entry.getValue());
        }
    }
}

访问DAO类:

public class FilaChamadoDAO extends GenericDAO<FilaChamado> {

    private static final long serialVersionUID = 1L;

    public FilaChamadoDAO() {
        super(FilaChamado.class);
    }

public List<FilaChamado> findTicketsByFila(int idFila,String listType) {
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("filaNumber", idFila);
        parameters.put("listParam", listType);

        return super.findListResult(FilaChamado.FIND_TICKETS_FILA_BY_FILA, parameters);
    }

Ai eu tenho uma classe facade para cada模型meu,que faz a interface de acesso ao DAO:

每个Facade类都有一个Model类,它构成了DAO访问接口:

 public class FilaChamadoFacade {

        private FilaChamadoDAO FilaChamadoDAO = new FilaChamadoDAO();

        public List<FilaChamado> listAll() {
            FilaChamadoDAO.beginTransaction();
            List<FilaChamado> result = FilaChamadoDAO.findAll();
            FilaChamadoDAO.closeTransaction();
            return result;
        }

public List<FilaChamado> findTicketsByFila(int idFila,String listaDestino) {
        List<FilaChamado> result = null;
        try {
            FilaChamadoDAO.beginTransaction();
            result = FilaChamadoDAO.findTicketsByFila(idFila, listaDestino);
            FilaChamadoDAO.flush();
        } catch (HibernateException e) {
            if (FilaChamadoDAO != null) {
                FilaChamadoDAO.rollback();
            }
            e.printStackTrace();
        } finally {
            FilaChamadoDAO.closeTransaction();

        }
        return result;
    }

当我调用ListAll()函数或任何namedWaury时,我无论如何都无法关闭这些打开的连接。 我在Main课程中做了一个简单的测试:

public class TestNamedQuery {
    public static void main(String[] args) {

        TrelloUser trelloU = new TrelloUser();
        TrelloUserFacade facade2 = new TrelloUserFacade();
        List<TrelloUser> trelloUsers1 = new ArrayList<TrelloUser>();
        trelloUsers1 = facade2.listAll();

        for (TrelloUser trelloUser : trelloUsers1) {
            if(trelloUser.getUserToken() != null) {
                System.out.println("Selectss do usuario: "+trelloUser.getUserName());
                ChamadoCard cards = new ChamadoCard();
                cards.InsereChamado(trelloUser);
            }
        }


    }
}

正如您所看到的,在每次启动事务时,在我的facade类中,我关闭它,但这不会发生在Oracle中,其中为我的EntityManager的每个beginTransaction创建了一个会话。

1 个答案:

答案 0 :(得分:1)

经过多次尝试后,我发现一条帖子说每次我向我的实体经理调用commit方法时都必须rollbackbeginTransaction()。 所以我在GenericDA.java类中更改了我的代码:

public void closeTransaction() {
        em.getTransaction().commit();
        em.close();
    }

我仍然试图理解为什么Hibernate强迫我甚至在查询语句中执行COMMIT,我认为如果不这样做我就能获得很好的表现。 但这种改变对我来说就像是一种魅力。