Hibernate无法初始化代理 - 在线程中访问Object时没有Session

时间:2016-07-27 07:23:04

标签: java spring multithreading hibernate spring-data

如何设置Thread类以便能够访问父类可以访问的会话?

目前,父类正在使用SomeObject,其中包含多个Set个对象。这些对象必须由DeviceRunner扩展Thread使用。

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

更新

@Autowire repository是否可以像@Controller那样@Autowiredrepository Repository如下所示返回null。

设置@Transactional让我可以处理SomeObject的对象但是我无法将Autowire转到@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 .... } 所以我可以创建/保存?

谢谢

代码DeviceRunner扩展线程

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

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

}

代码SomeObject

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

}

TestRunRepository

@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());
  }
}

创建线程的Rest Controller

public static int getNumberOfBusinessDays(@Nonnull LocalDate from, @Nonnull LocalDate to) {
    int fromDateDayOfWeek = from.getDayOfWeek();
    int toDateDayOfWeek = to.getDayOfWeek();

    int daysWithoutWeekends = 5 * Weeks.weeksBetween(
            from.withDayOfWeek(DateTimeConstants.MONDAY), to).getWeeks();

    if (fromDateDayOfWeek == DateTimeConstants.SUNDAY) {
        fromDateDayOfWeek = DateTimeConstants.SATURDAY;
    }
    if (toDateDayOfWeek == DateTimeConstants.SUNDAY) {
        toDateDayOfWeek = DateTimeConstants.SATURDAY;
    }

    return daysWithoutWeekends - (fromDateDayOfWeek - toDateDayOfWeek);
}

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

您可以将带有传播的事务用作必需的,这是默认值。 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // Expand/contract the cell and invalidate size (doesn't work) // let cell = tableView.cellForRow(at: indexPath) as! ExpandingCell // cell.tap() // cell.invalidateIntrinsicContentSize() // Keep track of the selected index and configure the expand/contract state when the cell is remade tableView.deselectRow(at: indexPath, animated: false) expandedIndexPath = indexPath if(!expandedIndexPathArray.contains(indexPath)){ expandedIndexPathArray.append(indexPath) } else{ expandedIndexPathArray = expandedIndexPathArray.filter({$0 != indexPath}) } // Whenever a cell's intrinsicContentSize changes, it must be reloaded tableView.reloadRows(at: [indexPath], with: .none) }