Я использую Spring и JPA в своем приложении, но в последнее время я немного запутался с использованием коллекций из DomainObjects.
Например:
Представьте, что у нас есть две таблицы: родительская и детская. Родитель может иметь несколько детей (@OneToMany), а у ребенка может быть только один родитель (@ManyToOne). Я использую Spring для обработки моего контекста транзакции в моем ServiceLayer (не в шаблоне Dao - Unit of Work), который настроен в context-application.xml с помощью aop: config. Детские коллекции помечены как LazyLoading Collection. До сих пор все работало нормально.
Проблема теперь заключается в следующем:
Мне нужен метод в моей службе, который создает новый родительский элемент и вызывает другой метод в той же транзакции, чтобы выполнить некоторые вычисления с вновь созданным родительским элементом. В рамках этих расчетов я должен вызвать parent.getChildren (). Очевидно, это должно вернуть пустой набор, так как новый родительский объект не может иметь дочерних элементов во время создания, но по какой-то причине я возвращаю 'null' вместо пустого набора, что приводит к исключению NullpointerException
Чтобы создать родителя, я попробовал следующие методы EntityManager:
- с использованием entityManager.persist (parent) - не сработало, коллекция равна нулю после создания.
- Использование entityManager.merge (parent) и возврат нового управляемого экземпляра parent - имели тот же результат.
Оба привели к нулевому набору. Но я почти уверен, что эти вызовы находятся внутри одной и той же транзакции, потому что за пределами транзакции я получил бы исключение LazyLoadingException (вместо NullPointer), которое (afaik) является правильным в данный момент. С другой стороны, использование уже существующего родителя с entityManager.findById () привело к существующей коллекции (что означает, что она работает так, как ожидалось). Чтобы решить эту проблему, я попробовал несколько подходов, пока не нашел работающий:
entityManager.refresh (parent) после слияния / сохранения завершен, так как коллекции инициализируются при вызове refresh.
Но в уроках я никогда не видел, чтобы этот метод использовался. В JavaDoc EntityManager сказано, что слияние возвращает новые управляемые bean-компоненты, в то время как persist делает саму ссылку управляемой. Я догадался, что управляемый будет означать, что я уже могу использовать эти Коллекции в транзакции. Почему коллекции не инициализируются во время создания? Должен ли я инициализировать их самостоятельно в конструкторе Parent, например?
Интересно, сделал ли я что-то не так, или это правильный способ вызвать refresh () после того, как я создал новый Instance of Parent? Если да, то мне просто нужно разделить между постоянным и обновленным, как это рекомендуется в следующей статье: Реализации JPA и обновить вновь созданный объект после сохранения? Или я должен просто обновить Объект, когда мне действительно нужно использовать Коллекцию?
Надеюсь, вы могли бы последовать за мной, и я был бы признателен за любые рекомендации или решения, которые позволили бы мне разобраться в этом вопросе.
Большое спасибо,
ymene