![](/img/trans.png)
[英]org.hibernate.AssertionFailure: possible non-threadsafe access to the 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.