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. Which I return every time with 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. That's illegal.
Hibernate Sessions are not thread-safe whereas Hibernate SessionFactory is thread-safe.
So, make a separate DAO layer. Create single sessionfactory object and share it among the DAO classes.
Get a session for a single-threaded DB operation and close the session in that thread.
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.
I saw the code 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:
@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:
Suppose ExecDAO
interface and implementation 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.
This blog explains why its not good to use these two annotations together whether on a class or on an interface
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.