繁体   English   中英

JSON 映射问题:可能对 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM