我们有一个应用程序使用Hibernate连接到postgre数据库。我们使用C3P0作为连接池。
---类---
正在保存对象:
public Entity saveOrUpdate(Entity entity, User u) {
EntityTransaction tx = EntityManagerHelper.getEntityManager().getTransaction();
try {
if(!tx.isActive())
tx.begin();
Entity result = null;
if (getID(entity) == null) {
EntityManagerHelper.getEntityManager().persist(entity);
} else {
result = EntityManagerHelper.getEntityManager().merge(entity);
}
tx.commit();
return result;
} catch (RuntimeException re) {
re.printStackTrace();
tx.rollback();
throw re;
}
}
正在加载对象:
@SuppressWarnings("unchecked")
public List<Entity> findByProperty(String propertyName, final Object value,
final int... rowStartIdxAndCount) {
try {
final String queryString = "select model from " + clazz.getName()
+ " model where model." + propertyName + "= :propertyValue";
Query query = EntityManagerHelper.getEntityManager().createQuery(
queryString);
query.setParameter("propertyValue", value);
if (rowStartIdxAndCount != null && rowStartIdxAndCount.length > 0) {
int rowStartIdx = Math.max(0, rowStartIdxAndCount[0]);
if (rowStartIdx > 0) {
query.setFirstResult(rowStartIdx);
}
if (rowStartIdxAndCount.length > 1) {
int rowCount = Math.max(0, rowStartIdxAndCount[1]);
if (rowCount > 0) {
query.setMaxResults(rowCount);
}
}
}
final List<Entity> result = query.getResultList();
return result;
} catch (RuntimeException re) {
re.printStackTrace();
throw re;
}
}
创建EntityManagerFactory并获取EntityManager:
private static EntityManagerFactory emf;
private static final ThreadLocal<EntityManager> threadLocal = new ThreadLocal<EntityManager>();
public static EntityManager getEntityManager() throws HibernateException {
EntityManager session = (EntityManager) threadLocal.get();
if (session == null || !session.isOpen()) {
session = (emf != null) ? emf.createEntityManager()
: null;
threadLocal.set(session);
}
return session;
}
在日志中,我看到了以下内容,但我不知道它是否与我们的问题有关:
java.lang.Exception: DEBUG -- CLOSE BY CLIENT STACK TRACE
at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:491)
at com.mchange.v2.c3p0.impl.NewPooledConnection.close(NewPooledConnection.java:191)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.dest royResource(C3P0PooledConnectionPool.java:470)
at com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask.run(BasicResourcePool.ja va:964)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunn er.java:547)
谢谢你的帮助!:)
您的配置在我看来不正确:
“after_statement”只能在连接提供程序支持积极版本(并且能够为同一事务中的每个语句返回相同的连接)时使用。
hibernate可能会忽略AFTER_STATEMENT(因为hibernate检测到此发布模式与您的设置不兼容),而使用AFTER_TRANSACTION...但为了确保你没有错误地使用它,你把它
<property name="hibernate.connection.release_mode" value="auto" />
这将在非JTA环境中设置AFTER_TRANSACTION发布模式。
我不确定这会修复您的问题(因为有一些可能您已经在after_transaction模式下运行)。(如果它没有修复它,请评论和一个更深入的调查将被要求)。
我能看到的重新创建sessionFactory的唯一原因是如果您的应用程序在运行时更改了数据模型--即。创建新的表或列(只有在应用程序同时修改映射文件或字节代码以添加新的注释、字段和类时,这些更改才会被新的会话工厂看到)。我想你不会那样做的。
编辑2
正如我在前面编辑中所说:避免重建SessionFactory。将此方法设为私有,以便确保不会多次调用它。如果您的代码正在重新构建sessionFactory,它可能是问题的原因,因为新的sessionFactory可能会消耗一些连接--由于相关的C3PO设置)。
编辑3(作为对您上次评论的回复)
您正面临一个非常常见的建筑设计问题,假设有2种方法可以解决它。好的和(非常)坏的。
(非常)糟糕的一个:在视图中使用open session模式。
在我看来,这种方法只能用于小的--非关键的--永远不会有巨大负载或大数据量的应用程序。
好的一个:使用分层架构。
视图层不接触实体管理器。这一层从控制器层接收要显示的数据,所有的数据都在那里:这里不需要取懒散的集合。
另外,控制器层必须向视图层提供完整的对象图。完整对象图意味着如果视图需要显示来自该集合的数据,视图层将不会接收到未初始化的惰性集合。
道层:
DAO层必须提供广泛的查询来获取该实体,不管它是否具有懒惰集合,以便满足控制器层的所有需求。
分层体系结构方法的主要优点是,您在开发过程中很快就会看到视图的需求,并且您将能够在需要时调整和优化您的查询。(即,您需要一个一个地修复所有的lazy-init异常,但这将使您对视图的需求有一个很好的了解)
我的JAVA应用程序使用多线程一次处理多个请求。因此,不同的请求在同一时间用不同的线程进行处理。 如果我观察数据库中打开的会话,有10个打开的会话(在c3p0中配置的最大数量),但它们都是空闲的。有没有一种方法可以让c3p0释放一些空闲连接,这样,至少有一个线程结束它的进程(增加最大连接数)?
C3P0不会在事务完成后释放连接。下面是堆栈跟踪: 池配置和事务配置如下: 如有任何建议,我将不胜感激
null 如果我理解正确的话,我们应该在启动时有1个空闲连接,根据负载从0到3,对吗? 正在发生的情况是:启动时1个连接,如果负载较低,最多3个空闲连接,高负载后超过3个空闲连接。然后这些连接不会立即关闭,我们不知道它们何时/是否会关闭(有时它们中的一些会关闭)。 所以问题是:这种行为正常吗? DAO子类的使用示例:
我在上一篇文章java中试图解决我的问题。sql。SQLRecoverableException:已关闭连接。我尝试了c3p0连接。财产如下:, 在JBOSS中部署之后,我开始测试我的web。一开始,它工作得很好,甚至更快。10分钟后,继续加载并超时。当通过服务器时。日志我得到了如下一些警告消息。 请给出一些解决这个问题的想法。
这与之前未解决的一个帖子有关:这里C3P0似乎在Heroku上初始化连接池后立即进入死锁。这个问题不会发生在我的本地邮件上。 [DEBUG]“com.mchange.v2.resourcepool.basicresourcepool”2015-07-05 07:12:59,132:成功终止获取系列。递减的pending_acquires 1,Attests_Retailing:30 [DEBUG]
我有一个应用程序,它将C3p0与Hibernate5和Hibernate使用。我想尝试使用Hikari,但我无法运行该应用程序。 专家 Hibernate版本为:5.2.17.Final Spring配置 我尝试了上述方法的不同排列,包括将用户名和密码直接传递给数据源: 但是我总是以这个错误结束: 这是由光函数引起的: