簡體   English   中英

JSON 映射問題:可能對 session 進行非線程安全訪問

[英]JSON mapping problem: possible non-threadsafe access to the session

我面臨一個我不知道的問題,你能遇到這個問題嗎?

JSON mapping problem: <package>ApiResponse["data"]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: possible non-threadsafe access to the session (through reference chain: <package>.ApiResponse["data"])

我有一個標准的 API 響應 pojo。 我每次都用 ResponseEntity 返回。 一切正常,但有時我得到了上述錯誤。 我不知道為什么會發生這個錯誤。

我從控制台獲得了以下日志

an assertion failure occurred (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: possible non-threadsafe access to the session

org.hibernate.AssertionFailure: possible non-threadsafe access to the session

我認為您正在嘗試在多個線程中共享相同的 Hibernate session 。 那是違法的。

Hibernate 會話不是線程安全的,而 Hibernate SessionFactory 是線程安全的。

因此,制作一個單獨的 DAO 層。 創建單個 sessionfactory object 並在 DAO 類之間共享。

為單線程數據庫操作獲取 session 並關閉該線程中的 session。

例如:

@Repository
public class DAO {

    @Autowired
    private SessionFactory sessionFactory;

    public class performDBOperation(Object obj) {
      Session session = sessionFactory.currentSession();
      session.save(obj);
      session.close(); 
    }

}

現在,我查看了您的 github 代碼。

我看到了代碼 Exec.java

@Service
public interface Exec {

    @Async
    @Transactional
    public void run();
}

這是不正確的。

更新:

public interface Exec {

    public void run();
}

將 ExecImpl 更新為此:

@Service
public class ExecImpl implements Exec {

    @Autowired
    private ExecDAO execDAO;

    @Override
    @Async
    @Transactional
    public void run() {
       // example : create an object to save it.
       Object object = ...; 
       execDAO.saveItem(object);
    }
}

創建 DAO 層:

假設ExecDAO接口和實現ExecDAOImpl

 public interface ExecDAO {

        public void saveItem(Object obj);

        // keep here abstract method to perform DB operation 
 }

    @Repository
    public class ExecDAOImpl implements ExecDAO {

        @Autowired
        private SessionFactory sessionFactory;

        @Override
        public void saveItem(Object obj) {
          Session session = sessionFactory.currentSession();
          session.save(obj);
          session.close(); 
        }
    }

查看您在評論中共享的鏈接中的代碼,我認為

@Async
@Transactional

是一件危險的事情。 我建議您提取一種方法來進行交易並嘗試我的意思是,

interface ExecImpl{
  @Async
  void run(){
     someThingElse.doTransaction();
  }
}

interface SomeThingElse{
  @Transactional
  void doTransaction();
}

我仍然不相信這會對你有所幫助。 但這是你可以嘗試的。

我還建議使用readonly事務來獲取數據,而不是為所有目的使用單個事務。

此博客解釋了為什么在 class 或接口上同時使用這兩個注釋不好

暫無
暫無

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

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