Hibernate DAO 会留下打开的连接



我正在使用Hibernate来管理一个非常简单的单表数据库。我曾经使用过基于 eclipse-link 的示例,但这给我带来了问题,所以我切换到休眠。

我确实遵循了本教程休眠-jpa-dao-example。

它看起来非常复杂,但问题很简单:我的服务器充满了剩余的连接。我有应用程序托管在HEROKU上。它可以工作,但是在几个请求之后,连接池(20(全部被吃掉,应用程序停止响应,我什至无法通过CLI连接。即使在同一函数中从客户端启动 3 个请求也会占用 3 个连接。

SEVERE: Connection error: 
org.postgresql.util.PSQLException: FATAL: too many connections for role "fjodybratyjsdp"

有人可以纠正我的 DAO 吗?我无法弄清楚为什么连接没有关闭

public class ParksDAO {
    private static final String HIBERNATE_CFG_XML = "hibernateAPP1.cfg.xml";
private static ParksDAO instance;
private Session currentSession;
private Transaction currentTransaction;
private ParksDAO() {
}
public static ParksDAO getInstance() {
    if (instance == null) {
        instance = new ParksDAO();
    }
    return instance;
}
    public Session openCurrentSession() {
        currentSession = getSessionFactory().openSession();
        return currentSession;
    }
    public Session openCurrentSessionwithTransaction() {
        currentSession = getSessionFactory().openSession();
        currentTransaction = currentSession.beginTransaction();
        return currentSession;
    }
    public void closeCurrentSession() {
        currentSession.close();
    }
    public void closeCurrentSessionwithTransaction() {
        currentTransaction.commit();
        currentSession.close();
    }
    private static SessionFactory getSessionFactory() {
        Configuration configuration = new Configuration().configure(HIBERNATE_CFG_XML);
        configuration.addAnnotatedClass(Park.class);
        StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
                .applySettings(configuration.getProperties());
        SessionFactory sessionFactory = configuration.buildSessionFactory(builder.build());
        return sessionFactory;
    }
    public Session getCurrentSession() {
        return currentSession;
    }
    public void setCurrentSession(Session currentSession) {
        this.currentSession = currentSession;
    }
    public Transaction getCurrentTransaction() {
        return currentTransaction;
    }
    public void setCurrentTransaction(Transaction currentTransaction) {
        this.currentTransaction = currentTransaction;
    }
    public Park persist(Park entity) {
        getCurrentSession().save(entity);
        return entity;
    }
    public void update(Park entity) {
        getCurrentSession().update(entity);
    }
    public Park merge(Park entity) {
        return (Park) getCurrentSession().merge(entity);
    }
    public Park findById(String id) {
        Park item = (Park) getCurrentSession().get(Park.class, id);
        return item; 
    }
    public void delete(Park entity) {
        getCurrentSession().delete(entity);
    }
}

持久性服务

public class ParkPersistencyService {
    private static ParksDAO parkDAO;
    public static Park savePark(Park entity) {
        parkDAO = ParksDAO.getInstance();
        parkDAO.openCurrentSessionwithTransaction();
        Park p = parkDAO.persist(entity);
        parkDAO.closeCurrentSessionwithTransaction();
        return p;
    }
    public static Park updatePark(Park entity) {
        parkDAO = ParksDAO.getInstance();
        parkDAO.openCurrentSessionwithTransaction();
        Park newEntity = parkDAO.merge(entity);
        parkDAO.closeCurrentSessionwithTransaction();
        return newEntity;
    }
    public static void removePark(Park p) {
        parkDAO = ParksDAO.getInstance();
        parkDAO.openCurrentSessionwithTransaction();
        parkDAO.delete(p);
        parkDAO.closeCurrentSessionwithTransaction();
    }
    public static Park getParkById(int id) {
        parkDAO = ParksDAO.getInstance();
        parkDAO.openCurrentSession();
        Park book = (Park) parkDAO.getCurrentSession().get(Park.class, id);
        parkDAO.closeCurrentSession();
        return book;
    }
    public static List<Park> getAllParks() {
        parkDAO = ParksDAO.getInstance();
        parkDAO.openCurrentSession();
        List<Park> books = (List<Park>) parkDAO.getCurrentSession().createQuery("from Park").list();
        parkDAO.closeCurrentSession();
        return books;
    }

休眠APP1.cfg.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
   <session-factory>
   <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
   <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
   <property name="hibernate.connection.url">jdbc:postgresql://ec2-54-247-101-191.eu-west-1.compute.amazonaws.com:5432/diaqjdbn90g1o</property>
   <property name="hibernate.connection.username">dmwykddcycwmtm</property>
   <property name="hibernate.connection.password">1a56ef9ccd4f3535f09a10a0c846518d7608bb6b677a1649d5036d02d3ae4aaa</property>
   <property name="hibernate.hbm2ddl.auto">update</property>
   <property name="show_sql">false</property>
   <property name="hibernate.current_session_context_class">thread</property>
   <property name="connection.pool_size">20</property>
</session-factory>
</hibernate-configuration>

如何不要每次都在函数中创建 parkDAO。而是在构造函数中创建它并重用它,如下所示:

public ParkPersistencyService() {
   parkDAO = new ParksDAO();
}
public static Park savePark(Park entity) {
    parkDAO.openCurrentSessionwithTransaction();
    Park p = parkDAO.persist(entity);
    parkDAO.closeCurrentSessionwithTransaction();
    return p;
}

最新更新