我正在使用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从EntityManagerFactory单例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不需要之后就被关闭了。提前感谢你在这个问题上所做的任何努力:)