簡體   English   中英

Hibernate不在新線程{org.hibernate.exception.GenericJDBCException:無法提取ResultSet}中從數據庫加載數據

[英]Hibernate is not loading the data from DB in new thread {org.hibernate.exception.GenericJDBCException: could not extract ResultSet}

我正在使用Spring Boot和Hibernate。 當我嘗試在新線程中加載數據(來自PostgreSQL)時,hibernate給出了異常。 但是,如果我在單個線程中執行代碼,則效果很好。 以下是此代碼段。

Customer.java

@Entity
public class Customer {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    private String name;

    @OneToMany(cascade=CascadeType.ALL)
    private List<UserEntity> entityList = new ArrayList<UserEntity>();
}

UserEntity.java

@Entity
public class UserEntity {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    private Customer customer;
}

服務層

public class EmailServiceImpl {

    public void someFunction() {
        Customer cus = customerRepo.findOne(1l);
        new Thread(() -> {
            cus.getEntityList().isEmpty(); // Below mentioned exception is pointing to this line
            // executing some operations based on the size of above list
        }).start();
    }

}

嘗試執行上述方法時發生異常/錯誤

org.hibernate.exception.GenericJDBCException: could not extract ResultSet
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.getResultSet(AbstractLoadPlanBasedLoader.java:434) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeQueryStatement(AbstractLoadPlanBasedLoader.java:186) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:121) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:88) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:688) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:75) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1991) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:570) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:252) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:566) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:135) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection$1.doWork(AbstractPersistentCollection.java:164) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection$1.doWork(AbstractPersistentCollection.java:149) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:252) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:148) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.collection.internal.PersistentBag.isEmpty(PersistentBag.java:266) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at com.e2log.service.impl.EmailServiceImpl.lambda$3(EmailServiceImpl.java:505) ~[classes/:na]
    at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_161]
Caused by: org.postgresql.util.PSQLException: This statement has been closed.
    at org.postgresql.jdbc.PgStatement.checkClosed(PgStatement.java:649) ~[postgresql-9.4.1212.jre7.jar:9.4.1212.jre7]
    at org.postgresql.jdbc.PgStatement.getMaxRows(PgStatement.java:485) ~[postgresql-9.4.1212.jre7.jar:9.4.1212.jre7]
    at org.postgresql.jdbc.PgStatement.createResultSet(PgStatement.java:158) ~[postgresql-9.4.1212.jre7.jar:9.4.1212.jre7]
    at org.postgresql.jdbc.PgStatement$StatementResultHandler.handleResultRows(PgStatement.java:210) ~[postgresql-9.4.1212.jre7.jar:9.4.1212.jre7]
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2092) ~[postgresql-9.4.1212.jre7.jar:9.4.1212.jre7]
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:288) ~[postgresql-9.4.1212.jre7.jar:9.4.1212.jre7]
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:430) ~[postgresql-9.4.1212.jre7.jar:9.4.1212.jre7]
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:356) ~[postgresql-9.4.1212.jre7.jar:9.4.1212.jre7]
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:168) ~[postgresql-9.4.1212.jre7.jar:9.4.1212.jre7]
    at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:116) ~[postgresql-9.4.1212.jre7.jar:9.4.1212.jre7]
    at sun.reflect.GeneratedMethodAccessor144.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_161]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_161]
    at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114) ~[tomcat-jdbc-8.5.27.jar:na]
    at com.sun.proxy.$Proxy215.executeQuery(Unknown Source) ~[na:na]
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]

正在執行代碼但不適合我的方案

  1. 單線程執行(即注釋/刪除兩行new Thread(() -> {}).start();
  2. 急切裝載的數據(即改變線@OneToMany(cascade=CascadeType.ALL)@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER)Customer.java
    1. 編寫該行cus.getEntityList().isEmpty(); cus.getEntityList().size(); new Thread(() -> { 。行上方new Thread(() -> {如果我們試圖在開始新線程之前查找大小,我認為hibernate正在加載數據)

有什么方法可以使並發代碼工作,而無需使用Eager加載?

僅供參考,春季啟動版本:1.5.10。發布Java:1.8 PostgreSQL:9.5

Spring使用的事務上下文存儲在線程局部變量中。 因此,如果您啟動一個新線程,或使用可調用對象在另一個線程中執行代碼,則該代碼將不會成為Spring事務方面啟動的事務的一部分。

相反,如果您想使用從數據庫中提取的某些數據來處理某些異步操作,則應首先從數據庫中將數據加載到變量中,然后將該加載的數據傳遞給異步線程以進行進一步處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM