![](/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.