java - 如何修复休眠中的连接泄漏?
问题描述
我不断收到一个例外:
org.hibernate.HibernateException: The internal connection pool has reached its maximum size and no connection is currently available!
我读了这个问题,但它对我没有帮助
Java/Hibernate - 异常:内部连接池已达到其最大大小,当前没有可用的连接
所以,这是我的代码:
休眠管理器
package beans.database;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import javax.ejb.Singleton;
/**
* The type Hibernate manager.
*
*/
@Singleton
public class HibernateManager {
private StandardServiceRegistry registry;
private SessionFactory sessionFactory;
/**
* Gets session.
*
*
*
* @return the session
*/
public Session getSession() {
if (sessionFactory == null) {
try {
// Create SessionFactory
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Exception e) {
e.printStackTrace();
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
final Session session = sessionFactory.openSession();
return session;
}
/**
* Shutdown.
*/
public void shutdown() {
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
它是如何使用的
@Singleton
@LocalBean
public class FieldChecker {
@EJB
HibernateManager hibernateManager;
public Boolean isUserFieldExist(String field, String value) {
final Session session = hibernateManager.getSession();
Criteria criteria = session.createCriteria(UserEntity.class);
criteria.add(Restrictions.eq(field, value));
criteria.setProjection(Projections.rowCount());
long count = (long) criteria.uniqueResult();
session.close();
return count != 0;
}
}
用户实体
package entities;
import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Objects;
@Entity
@Table(name = "user", schema = "pump_coin")
public class UserEntity {
private long id;
private String name;
private String email;
private Long phone;
private Double height;
private Double weight;
private Double foot;
private String unit;
private Double target;
private byte verification;
private Timestamp date;
private String password;
private Integer age;
private String sex;
@Column(name = "id")
@Id
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Column(name = "phone")
public Long getPhone() {
return phone;
}
public void setPhone(Long phone) {
this.phone = phone;
}
@Column(name = "height")
public Double getHeight() {
return height;
}
public void setHeight(Double height) {
this.height = height;
}
@Column(name = "weight")
public Double getWeight() {
return weight;
}
public void setWeight(Double weight) {
this.weight = weight;
}
@Column(name = "foot")
public Double getFoot() {
return foot;
}
public void setFoot(Double foot) {
this.foot = foot;
}
@Column(name = "unit")
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
@Column(name = "target")
public Double getTarget() {
return target;
}
public void setTarget(Double target) {
this.target = target;
}
@Column(name = "verification")
public byte getVerification() {
return verification;
}
public void setVerification(byte verification) {
this.verification = verification;
}
@Column(name = "date")
public Timestamp getDate() {
return date;
}
public void setDate(Timestamp date) {
this.date = date;
}
@Column(name = "password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Column(name = "age")
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Column(name = "sex")
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserEntity that = (UserEntity) o;
return id == that.id && verification == that.verification && Objects.equals(name, that.name) && Objects.equals(email, that.email) && Objects.equals(phone, that.phone) && Objects.equals(height, that.height) && Objects.equals(weight, that.weight) && Objects.equals(foot, that.foot) && Objects.equals(unit, that.unit) && Objects.equals(target, that.target) && Objects.equals(date, that.date) && Objects.equals(password, that.password) && Objects.equals(age, that.age) && Objects.equals(sex, that.sex);
}
@Override
public int hashCode() {
return Objects.hash(id, name, email, phone, height, weight, foot, unit, target, verification, date, password, age, sex);
}
}
休眠.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:mysql://my/url</property>
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
<property name="hibernate.connection.pool_size">100</property>
<property name="hibernate.c3p0.timeout">1800</property>
<mapping class="entities.UserEntity"/>
<mapping class="entities.CoinBalanceEntity"/>
<!-- DB schema will be updated if needed -->
<!-- <property name="hibernate.hbm2ddl.auto">update</property> -->
</session-factory>
</hibernate-configuration>
我怀疑我以某种方式错误地注入了 HibernateManager,结果我得到了很多连接工厂。
解决方案
使用 Hibernate 会话时,无论如何都必须确保始终关闭它。这意味着您的方法应该使用 try-finally 模式。
public Boolean isUserFieldExist(String field, String value) {
final Session session = hibernateManager.getSession();
try {
Criteria criteria = session.createCriteria(UserEntity.class);
criteria.add(Restrictions.eq(field, value));
criteria.setProjection(Projections.rowCount());
long count = (long) criteria.uniqueResult();
return count != 0;
} finally {
session.close();
}
}
您必须在使用创建新会话的任何地方执行此操作。虽然一般来说,如果您使用的是带有 EJB 注入的综合系统,您应该只注入一个EntityManager
而不是像这样手动管理它。
推荐阅读
- javascript - Firebase 身份验证错误 - 每当我尝试使用谷歌登录时
- python - 如何从python中字符串类型的字典键中获取整数?
- python - Skit-learn with Spacy parallelization error with RandomizedSearchCV
- javascript - How to get values from two textboxes and display on third on button click using Javascript?
- assembly - How to disassemble fasm-generated binary?
- c++ - 是防止部分读取原子存储所必需的“memory_order_relaxed”
- mysql - Use subgroups in databases
- r - 从 R 中不可用的 URL 加载数据集,仅从本地加载:设置问题?
- angular - Creating volume in custom Docker image on GCP causing error
- javascript - 由按钮控制的可折叠 HTML 表格,带有多个具有不同数据集的子表格