我在使用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创建了一个会话。
答案 0 :(得分:1)
经过多次尝试后,我发现一条帖子说每次我向我的实体经理调用commit
方法时都必须rollback
或beginTransaction()
。
所以我在GenericDA.java
类中更改了我的代码:
public void closeTransaction() {
em.getTransaction().commit();
em.close();
}
我仍然试图理解为什么Hibernate强迫我甚至在查询语句中执行COMMIT,我认为如果不这样做我就能获得很好的表现。 但这种改变对我来说就像是一种魅力。