Spring Data JPA Не удалось инициализировать прокси - нет сеанса при запуске в другом потоке в .parallel () - PullRequest
0 голосов
/ 15 марта 2019

У меня проблема с этим кодом, когда я пытаюсь запустить его параллельно и выполнять ленивую инициализацию некоторых объектов в MyObject. Независимо от того, какая лямбда не работает в главном потоке, получит исключение:

не удалось лениво инициализировать коллекцию ролей: my.package.model.I18String.translations, не удалось инициализировать прокси - без сеанса

Как сделать сеанс доступным в каждом лямбда-потоке?

@Service
public class MyService {

  @Autowired
  private JpaRepo1 repo1;
  @Autowired
  private JpaRepo2 repo2;


  public List<Result> find(String param1, Long param2, Locale param3) {
    return Stream.of(
        findResults1(query, webGroupId, lang),
        findResults2(query, webGroupId, lang))
        **.parallel()**
        .map(Supplier::get)
        .flatMap(Collection::stream)
        .collect(toList());
  }

  private Supplier<List<Result>> findResults1(String param1, Long param2, Locale param3) {
    return () -> repo1.findByNameContains(param1, param2, param3)
        .stream()
        .map(cat -> toResult(cat, param3))
        .collect(toList());
  }

  private Supplier<List<Result>> findResults2(String param1, Long param2, Locale param3) {
    return () -> repo2.findByNameContains(param1, param2, param3)
        .stream()
        .map(pg -> toResult(pg, param2, param3))
        .collect(toList());
  }
  private Result toResult(MyObject obj, Locale lang) {
    SearchResult result = new SearchResult();
    result.setResultId(obj.getId());
    **result.setResultName(obj.getName().getString(lang));** // <=====
    result.setTags(obj.getTags().stream().map(Tag::getId).collect(toList()));
    return result;
  }

1 Ответ

1 голос
/ 18 марта 2019

То, что вы видите, работает как спроектировано в соответствии со спецификацией JPA (читай: не имеет никакого отношения к вовлечению Spring Data JPA здесь).JPA EntityManager определен как связанный с потоком, что в конечном итоге означает, что состояние отложенной загрузки сущности также.

Таким образом, для параллельной обработки объектов необходимо убедиться, что они полностью инициализированы,В идеале вы должны запускать запросы, которые возвращают неизменяемые DTO, так что экземпляры a являются поточно-ориентированными.

...