JSON映射问题:对会话的可能的非线程安全访问

问题描述 投票:0回答:2

我正面临一个我不知道的问题,您能面对这个问题吗?

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
java spring-boot spring-mvc
2个回答
0
投票

查看您在注释中共享的链接的代码,我认为是

@Async
@Transactional

是危险的事情。我建议您提取一种方法来进行交易并尝试我的意思是,

interface ExecImpl{
  @Async
  void run(){
     someThingElse.doTransaction();
  }
}

interface SomeThingElse{
  @Transactional
  void doTransaction();
}

我仍然不相信这会对您有帮助。但这是您可以尝试的。

我也建议使用readonly事务来获取数据,而不是出于所有目的都没有一个事务。


0
投票

我认为您正在尝试在多个线程中共享相同的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(); 
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.