【问题标题】:Hibernate could not initialize proxy - no Session when accessing Object within a ThreadHibernate 无法初始化代理 - 在线程中访问对象时没有会话
【发布时间】:2016-07-27 07:23:04
【问题描述】:

如何设置我的Thread 类以能够访问父类有权访问的会话?

当前父类使用SomeObject,它有多个Set 的对象。扩展ThreadDeviceRunner 需要使用这些对象。

此应用程序正在使用 Spring Boot/Spring Data JPA/Hibernate。

更新

是否可以像 @Controller 一样 @Autowire repository?如下图@Autowiredrepository返回null。

设置@Transactional 允许我处理SomeObject 的对象,但我无法将Repository 获取到Autowire,所以我可以创建/保存?

谢谢

代码 DeviceRunner 扩展线程

@Transactional(propagation=Propagation.REQUIRED)
public class DeviceRunner extends Thread {

    @Autowired
    public TestRunRepository repository;

    public SomeObject object;        

    private .....

    public DeviceRunner(args.... ) {
        // set private variables
    }

    public void run() {
        // do stuff
    }

    synchronized ....

}

编码 SomeObject

@Data
@Entity
@Table(name = "test_run")
public class SomeObject {

  @ManyToMany(fetch = FetchType.LAZY)
  private Set<OtherObjects> otherObjects;

}

TestRunRepository

@Repository
@Transactional
public interface TestRunRepository extends PagingAndSortingRepository<TestRun, Long> {

}

创建线程的Rest Controller

@Transactional(propagation=Propagation.REQUIRED)
 @RestController
public class HomeController {

 @Autowired
 public TestRunRepository repository;
  ....
  @Transactional
  private void runTestRunOnDevice(TestRun testRun) {


      DeviceRunner deviceRunner = new DeviceRunner(testRun);
      deviceRunner.start();
      while (deviceRunner.isAlive());
  }
}

【问题讨论】:

  • 你需要从线程中修改SomeObject还是直接读取?
  • 你确定你没有在调用方法中丢失@Transactional(readOnly = true) 吗?

标签: java spring multithreading hibernate spring-data


【解决方案1】:

您可以使用带有传播的事务作为必需的,这是默认的。 @Transactional(Propagation.REQUIRED)

【讨论】:

  • 在设置 Transactional(Propogation.REQUIRED) 时是否需要这样做?这看起来可以让我从 SomeObject 访问对象,但存储库没有正确自动装配,所以我没有办法在线程中访问它们。我已经更新了上面的代码
【解决方案2】:

我会将 @Autowired EntityManagerSession 添加到您的 Repository 类中。有用。 Spring Data 注入一个代理,该代理会产生实际的 EntityManager/Session,具体取决于事务上下文(即取决于调用它的当前执行线程)。

【讨论】:

  • 如上所示设置 Autowired 不允许将存储库连接到类。我必须以不同的方式执行此操作吗?目前我将它作为构造函数的一部分传递,但更愿意让它自动装配。
  • 要么注释一个像'@Autowired Repository(EntityManager em)'这样的构造函数,或者像'@Autowired void setEntityManager(EntityManager em)'这样的setter或字段(从可测试性的角度来看不太推荐)。所有 3 种方式都应该有效。
猜你喜欢
  • 2012-11-09
  • 2010-11-15
  • 1970-01-01
  • 1970-01-01
  • 2015-10-09
  • 1970-01-01
  • 2016-12-27
  • 1970-01-01
  • 2014-01-14
相关资源
最近更新 更多