[英]JSON mapping problem: possible non-threadsafe access to the session
I am facing a problem due which is unknown to me, can you one have faced this problem?我面临一个我不知道的问题,你能遇到这个问题吗?
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"])
I have a standard API response pojo.我有一个标准的 API 响应 pojo。 Which I return every time with ResponseEntity.
我每次都用 ResponseEntity 返回。 Everything is working fine, but sometimes I got that above error.
一切正常,但有时我得到了上述错误。 I don't why this error occurred.
我不知道为什么会发生这个错误。
I got the below log from console我从控制台获得了以下日志
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
I think you are trying to share same Hibernate session within multiple threads.我认为您正在尝试在多个线程中共享相同的 Hibernate session 。 That's illegal.
那是违法的。
Hibernate Sessions are not thread-safe whereas Hibernate SessionFactory is thread-safe. Hibernate 会话不是线程安全的,而 Hibernate SessionFactory 是线程安全的。
So, make a separate DAO layer.因此,制作一个单独的 DAO 层。 Create single sessionfactory object and share it among the DAO classes.
创建单个 sessionfactory object 并在 DAO 类之间共享。
Get a session for a single-threaded DB operation and close the session in that thread.为单线程数据库操作获取 session 并关闭该线程中的 session。
For example:例如:
@Repository
public class DAO {
@Autowired
private SessionFactory sessionFactory;
public class performDBOperation(Object obj) {
Session session = sessionFactory.currentSession();
session.save(obj);
session.close();
}
}
Now, I have looked at your github code.现在,我查看了您的 github 代码。
I saw the code Exec.java我看到了代码 Exec.java
@Service
public interface Exec {
@Async
@Transactional
public void run();
}
This is incorrect.这是不正确的。
Updated:更新:
public interface Exec {
public void run();
}
Update ExecImpl to this:将 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);
}
}
Create DAO layer:创建 DAO 层:
Suppose ExecDAO
interface and implementation ExecDAOImpl
:假设
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();
}
}
Looking at the code at the link you shared in the comment, I think that查看您在评论中共享的链接中的代码,我认为
@Async
@Transactional
is a dangerous thing.是一件危险的事情。 I would suggest you to extract a method to do the transactions and try what I mean is that,
我建议您提取一种方法来进行交易并尝试我的意思是,
interface ExecImpl{
@Async
void run(){
someThingElse.doTransaction();
}
}
interface SomeThingElse{
@Transactional
void doTransaction();
}
I am still not convinced this will help you.我仍然不相信这会对你有所帮助。 But this is something you can try.
但这是你可以尝试的。
I would also suggest to use readonly
transactions for getting data and not have a single transaction for all purposes.我还建议使用
readonly
事务来获取数据,而不是为所有目的使用单个事务。
This blog explains why its not good to use these two annotations together whether on a class or on an interface此博客解释了为什么在 class 或接口上同时使用这两个注释不好
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.