如何使用Hibernate释放连接?

时间:2019-07-06 12:24:31

标签: java spring hibernate

在我的Web应用程序中提出了一些请求后,我遇到了以下异常:

  

java.sql.SQLTransientConnectionException:HikariPool-1-连接不可用,请求在30002ms后超时。

为清楚起见,我没有配置连接池(光)。 在application.properties中有我所有的属性:

spring.datasource.url=jdbc:postgresql://localhost/authHibernate
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.driver-class-name=org.postgresql.Driver 
Method org.postgresql.jdbc.PgConnection.createClob() is not yet implemented.
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false  
for exceptions
logging.level.org.springframework.security=DEBUG
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
logging.level.org.hibernate.type=TRACE

我的目标是在我的Spring-Boot应用程序中使用常规的Hiberante(这不是使用所有这些JpaRepo <>和CrudRepo的简单Spring Data方法)。为此,我从EntityManager获得了会话,并像通常的Hibernate一样使用它。据我了解,数据源负责连接池。但是,这是JDBC。我应该如何使用Hibernate方式而不是JDBC方式修复连接池? 我有一个道课:

@Component
public class GrowBoxDaoImpl implements GrowBoxDao {

@Autowired
private EntityManagerFactory entityManagerFactory;

@Override
public List<GrowBox> findByUser(Long userId) {

    Session session = entityManagerFactory.unwrap(SessionFactory.class).openSession();
    String hqlQuery = "from GrowBox gb where gb.responsibleUser.id =: userId";
    Query query = session.createQuery(hqlQuery);
    query.setParameter("userId", userId);
    List growBoxes = query.getResultList();
    session.close();
    return growBoxes;
}

@Override
public GrowBox findById(Long id) {

    Session session = entityManagerFactory.unwrap(SessionFactory.class).openSession();
    GrowBox growBox = session.get(GrowBox.class, id);
    session.close();

    return growBox;
}

@Override
public GrowBox saveBox(GrowBox box) {
    Session session = entityManagerFactory.unwrap(SessionFactory.class).openSession();
    session.getTransaction().begin();
    session.saveOrUpdate(box);
    session.flush();
    session.getTransaction().commit(); // call flush too
    session.close();
    return box;
}

@Override
public void deleteBox(Long id) {

    String hqlQuery = "delete GrowBox where id =: id";
    Session session = entityManagerFactory.unwrap(SessionFactory.class).openSession();
    session.getTransaction().begin();

    session.createQuery(hqlQuery).setParameter("id", id).executeUpdate();
    session.flush();
    session.getTransaction().commit();
    session.close();
}
}

我有几个实体,每个实体都有Dao类和Service。还有一些使用我的服务的控制器。如果有帮助,请参阅我的应用程序的Git Repo:https://github.com/DennisKingsman/HibernateWithSpringBootExample

1 个答案:

答案 0 :(得分:1)

在典型的带有Spring引导的Hibernate情况下,您可以仅包含

@PersistenceUnit
private EntitiyManager entityManager;

,spring-boot会自动创建EntityManager。它还会自动保留EntityManagerFactory。无需显式使用EntityManagerFactory。这称为容器管理的事务。会话自动关闭。

EntityManager作为ThreadLocal进行管理(通过Spring-boot),因此您可能无法访问另一个线程中的同一线程。

另一种方法是使用应用程序管理的事务。在https://docs.oracle.com/cd/E19798-01/821-1841/bnbra/index.html

上了解它