我正面临一个我不知道的问题,您能面对这个问题吗?
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
查看您在注释中共享的链接的代码,我认为是
@Async
@Transactional
是危险的事情。我建议您提取一种方法来进行交易并尝试我的意思是,
interface ExecImpl{
@Async
void run(){
someThingElse.doTransaction();
}
}
interface SomeThingElse{
@Transactional
void doTransaction();
}
我仍然不相信这会对您有帮助。但这是您可以尝试的。
我也建议使用readonly
事务来获取数据,而不是出于所有目的都没有一个事务。
我认为您正在尝试在多个线程中共享相同的Hibernate会话。那是非法的。
Hibernate会话不是线程安全的,而Hibernate SessionFactory是线程安全的。
因此,请创建一个单独的DAO层。创建单个sessionfactory对象,并在DAO类之间共享它。
获取单线程数据库操作的会话,然后在该线程中关闭该会话。
例如:
@Repository
public class DAO {
@Autowired
private SessionFactory sessionFactory;
public class performDBOperation(Object obj) {
Session session = sessionFactory.currentSession();
session.save(obj);
session.close();
}
}
现在,我已经查看了您的git代码。
我看到了代码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 to save the object.
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;
public void saveItem(Object obj) {
Session session = sessionFactory.currentSession();
session.save(obj);
session.close();
}
}