Как инициализировать ленивую загруженную коллекцию за пределами транзакции, которую она была извлечена правильно?JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Как инициализировать ленивую загруженную коллекцию за пределами транзакции, которую она была извлечена правильно?

Сообщение Anonymous »

У меня приложение для пружинной загрузки, которое использует Hibernate в качестве структуры ORM и DGS в качестве двигателя GraphQL. Я боролся с поиском способов инициализации ленивой нагруженной коллекции, правильного пути. У меня следующий сценарий: < /p>

Код: Выделить всё

application.properties
# The below has been set to false to get rid of the anti-pattern stuff it introduces
spring.jpa.open-in-view=false
...
< /code>
@Entity
public class User {
@Id
@GeneratedValue
private UUID id;

@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List articles;

...

}
< /code>
@Entity
public class Article {
@Id
@GeneratedValue
private UUID id;

@ManyToOne(optional = false, fetch = FetchType.LAZY)
private User user;

...
}
Мой пользователь Fetcher Data выглядит примерно так:

Код: Выделить всё

@DgsComponent
public class UserDataFetcher {
@Autowired
private UserService userService;

@DgsQuery
public User getUserById(@InputArgument UUID id) {
return userService.findById(id);
}
...
}
my userservice выглядит примерно так:

Код: Выделить всё

@Service
public class UserServiceImpl implements UserService {

@Autowired
private UserRepository userRepository;

@Override
public User findById(UUID id) {
return userRepository.findById(id).orElseThrow(DgsEntityNotFoundException::new);
}
...
}

Теперь я хочу инициализировать/загрузить свои коллекции статей из DB, когда пользователь просит его в запросе GraphQL. Для этой цели я создал решатель для детей для своих статей, которые выполняются только тогда, когда пользователь запрашивает статью в запросе. My userdatafetcher начал выглядеть так:

Код: Выделить всё

@DgsComponent
public class UserDataFetcher {
@Autowired
private UserService userService;

@DgsQuery
public User getUserById(@InputArgument UUID id) {
return userService.findById(id);
}

@DgsData(parentType = "User", field = "articles")
public List getArticle(DgsDataFetchingEnvironment dfe) {
User user = dfe.getSource();
Hibernate.initialize(user.getArticles());
return user.getArticles();
}
...
}
< /code>
Но вышеупомянутое начало бросать исключения, сообщающие мне, что Hibernate не может найти открытый сеанс для приведенного выше запроса. Что имело смысл, потому что их не было, поэтому я поместил @transactional 
в дополнение к резолюру моего ребенка, и это начало выглядеть так:

Код: Выделить всё

@DgsComponent
public class UserDataFetcher {
@Autowired
private UserService userService;

@DgsQuery
public User getUserById(@InputArgument UUID id) {
return userService.findById(id);
}

@DgsData(parentType = "User", field = "articles")
@Transactional
public List getArticle(DgsDataFetchingEnvironment dfe) {
User user = dfe.getSource();
Hibernate.initialize(user.getArticles());
return user.getArticles();
}
...
}
< /code>
Тем не менее, приведенное выше не сработало. Я также попытался перенести этот @transactional 
в свой сервисный уровень, но даже тогда он не сработал, и это вызвало то же исключение. После долгих размышлений я основал, что (возможно) hibernate.initialize (...) работает только в том случае, если я позвоню в первоначальную транзакцию, которая в первую очередь принесла мне моего пользователя. Это означает, что это бесполезно для меня, так как мой вариант использования очень управляется пользователем. Я хочу получить это только тогда, когда мой пользователь спрашивает об этом, и это всегда будет в какой-то другой части моего приложения вне родительской транзакции. < /P>
Я ищу решения, отличные от следующих: < /p>
  • PrettyPrint-Override ">

    Код: Выделить всё

        @DgsData(parentType = "User", field = "articles")
    @Transactional
    public List getArticle(DgsDataFetchingEnvironment dfe) {
    User user = dfe.getSource();
    List articles = articlesRepository.getArticlesByUserId(user.getUserId);
    return articles;
    }
    < /code>
    Я не в пользу вышеупомянутого решения, поскольку я чувствую, что это недостаточно использует сам ОРМ, пытаясь разрешить отношение самостоятельно, а не позволяя самому спячке. (Исправьте меня, если я ошибаюсь так, думая так)
    
     Изменение моего пользователя 
    объекта для использования fetchmode.join .

Код: Выделить всё

@Entity
public class User {
@Id
@GeneratedValue
private UUID id;

@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
@Fetch(FetchMode.JOIN)
private List articles;
...

}
< /code>
Это то же самое, что и указывать Hibernate, чтобы с нетерпением загружать приведенную ниже коллекцию, несмотря ни на что. Я тоже этого не хочу. Не в пользу этого, так как это просто полосовая помощь для LazyInitializationExceptions 
.

Любые другие решения, которые просто забывают о ленивом>

Подробнее здесь: https://stackoverflow.com/questions/691 ... it-was-fet
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как реализовать ленивую инициализацию поля содержимого в объекте сущности?
    Anonymous » » в форуме JAVA
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous
  • Можно ли сделать ленивую группу из уже сортируемого потока, возвращая поток в Java 8?
    Anonymous » » в форуме JAVA
    0 Ответы
    18 Просмотры
    Последнее сообщение Anonymous
  • Лучший способ вызвать ленивую оценку в Pyspark и Polars для сравнительного анализа
    Anonymous » » в форуме Python
    0 Ответы
    3 Просмотры
    Последнее сообщение Anonymous
  • Лучший способ вызвать ленивую оценку в Pyspark и Polars для сравнительного анализа
    Anonymous » » в форуме Python
    0 Ответы
    3 Просмотры
    Последнее сообщение Anonymous
  • Составьте ленивую колонку очень отстаю при прокрутке
    Anonymous » » в форуме Android
    0 Ответы
    2 Просмотры
    Последнее сообщение Anonymous

Вернуться в «JAVA»