天天看点

java hibernate 释放连接池_java – Hibernate不从连接池释放连接

我正在使用Hibernate JPA创建一个应用程序,我使用c3p0与MySQL连接池。我有一个与MySQL数据库连接数量的问题,因为它触及了152个打开的连接,这是不需要的,因为我将c3p0配置文件中的最大池大小定义为20,当然我关闭每个实体管理器从EntityManagerFactory提交每个事务后。

每次执行一个控制器时,我注意到打开了7个以上的连接,如果我刷新,那么再次打开7个连接,而不会关闭过去的空闲连接。在我调用的每个DAO函数中,执行em.close()。我在这里承认,问题在我的代码中,但我不知道我在这里做错了什么。

这是Sondage.java实体:

@Entity

@NamedQuery(name="Sondage.findAll", query="SELECT s FROM Sondage s")

public class Sondage implements Serializable {

private static final long serialVersionUID = 1L;

public Sondage() {}

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private int id;

private String name;

private byte needLocation;

//bi-directional many-to-one association to ResultatSondage

@OneToMany(mappedBy = "sondage", cascade = CascadeType.ALL)

@OrderBy("sondage ASC")

private List resultatSondages;

//bi-directional many-to-one association to SondageSection

@OneToMany(mappedBy = "sondage", cascade = CascadeType.ALL)

private List sondageSections;

}

这是我的DAO类:

@SuppressWarnings("unchecked")

public static List GetAllSondage() {

EntityManager em = PersistenceManager.getEntityManager();

List allSondages = new ArrayList<>();

try {

em.getTransaction().begin();

Query query = em.createQuery("SELECT s FROM Sondage s");

allSondages = query.getResultList();

em.getTransaction().commit();

} catch (Exception ex) {

if (em.getTransaction().isActive()) {

em.getTransaction().rollback();

}

allSondages = null;

} finally {

em.close();

}

return allSondages;

}

如你所见,em关闭。在我的JSP中,我这样做:我知道这不是在视图中做事情的好方法。

الاستمارات

List allSondages = (List) request.getAttribute("sondages");

for (int i = 0; i < allSondages.size(); i++) {

%>

if (request.getSession().getAttribute("user") != null) {

Utilisateur user = (Utilisateur) request.getSession().getAttribute("user");

if (user.getType().equals("admin")) {

%>

تعديل

}

}

%>

}

%>

我猜测每次调用user.getType()时,都会建立一个请求?如果是这样,我该如何防止呢?

对于c4p0配置文件,我将其包含在persistence.xml中,我看到几个帖子说我需要将c3p0配置文件放在c3p0-config.xml中,但是通过我的设置,c3p0是通过持久性传递的值来初始化的.xml文件,mysql连接也达到152个连接,但maxpoolsize为20,这里是persistence.xml文件

xmlns="http://xmlns.jcp.org/xml/ns/persistence"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence

http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">

com.caoe.Models.ChoixQuestion

com.caoe.Models.Question

com.caoe.Models.Reponse

com.caoe.Models.ResultatSondage

com.caoe.Models.Section

com.caoe.Models.Sondage

com.caoe.Models.SondageSection

com.caoe.Models.SousQuestion

com.caoe.Models.Utilisateur

value=" org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider" />

value="jdbc:mysql://localhost:3306/caoe?useUnicode=yes&characterEncoding=UTF-8"/>

value="true" />

编辑:我正在将应用程序部署到使用Tomcat和MySQL安装的红帽服务器。我只是想知道为什么Hibernate打开太多的连接到MySQL,所有实体管理器关闭没有连接将保持打开,但情况并非如此。如果我是真的,当我做这样的事情时,连接被打开,我猜和纠正我:

List allSondages = SondageDao.getAllSondages();

for (Sondage sondage : allSondages) {

List questions = sondage.getQuestions();

//code to display questions for example

}

这里当我使用sondage.getQuestions()时,Hibernate是否打开一个数据库的连接,并且不会关闭它,在配置文件中,当我完成它之后,我发现关闭或返回连接池的某些东西。提前感谢任何帮助。

编辑2:

由于人们要求版本,所以他们是:

JAVA jre 1.8.0_25

Apache Tomcat v7.0

休眠核心-4.3.10

hibernate c3p0 4.3.10.final

hibernate-jpa 2.1

提前致谢

mysql版本是Mysql 5.6.17,如果这可以帮助…

编辑4:随着人们对于我发布的代码的巫婆版本感到困惑,让我编辑这个,所以你会知道会发生什么:

首先,我将从展示什么是错误代码开始,因为你们不在乎工作原理:

@SuppressWarnings("unchecked")

public static List GetAllSondage() {

EntityManager em = PersistenceManager.getEntityManager();

List allSondages = new ArrayList<>();

try {

em.getTransaction().begin();

Query query = em.createQuery("SELECT s FROM Sondage s");

allSondages = query.getResultList();

em.getTransaction().commit();

} catch (Exception ex) {

if (em.getTransaction().isActive()) {

em.getTransaction().rollback();

}

allSondages = null;

} finally {

em.close();

}

return allSondages;

}

所以这基本上是我为所有的dao功能所做的,我知道在这里不需要交易,因为我看到问题指出交易对于连接关闭很重要。除此之外,我从具有EntityManagerFactory单例对象的PersistenceManager类getEntityManager,所以getEntityManager从Ent​​ityManagerFactory单例Object中创建一个entityManager:=>代码好于1000字:

PesistenceManager.java:

import javax.persistence.EntityManager;

import javax.persistence.EntityManagerFactory;

import javax.persistence.Persistence;

public class PersistenceManager

{

private static EntityManagerFactory emf = null;

public static EntityManager getEntityManager()

{

return getEntityManagerFactory().createEntityManager();

}

public static EntityManagerFactory getEntityManagerFactory()

{

if(emf == null) {

emf = Persistence.createEntityManagerFactory("CAOE");

return emf;

}

else

return emf;

}

}

是的,这很酷,一切都很好,但问题在哪里?

这里的问题是这个版本打开连接,永远不要关闭它们,em.close()没有任何作用,它使连接打开到数据库。

noob修复:

为了解决这个问题,我为每个请求创建一个EntityManagerFactory,这意味着dao看起来像这样:

@SuppressWarnings("unchecked")

public static List GetAllSondage() {

//this is the method that return the EntityManagerFactory Singleton Object

EntityManagerFactory emf = PersistenceManager.getEntitManagerFactory();

EntityManager em = emf.createEntityManager();

List allSondages = new ArrayList<>();

try {

em.getTransaction().begin();

Query query = em.createQuery("SELECT s FROM Sondage s");

allSondages = query.getResultList();

em.getTransaction().commit();

} catch (Exception ex) {

if (em.getTransaction().isActive()) {

em.getTransaction().rollback();

}

allSondages = null;

} finally {

em.close();

emf.close();

}

return allSondages;

}

现在这是坏的,我会保持它,而我没有这个问题的答案(似乎是如此:D)。所以使用这个代码基本上所有的连接在hibernate不需要之后就被关闭了。提前感谢你在这个问题上所做的任何努力:)