Определенный граф объектов не принимается во внимание, когда приложение основано на Spring Boot. Напротив, во время тестов JUnit все работает нормально.
Домен довольно прост: книги и их категории (отношение «многие ко многим»).
Класс книги:
@Entity
@NamedEntityGraph(name = "Book.summary",
attributeNodes = { @NamedAttributeNode("book_id"), @NamedAttributeNode("title")})
public class Book {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long book_id;
private String title;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "BOOK_CATEGORY",
joinColumns = @JoinColumn(name = "book_id", referencedColumnName = "book_id"),
inverseJoinColumns = @JoinColumn(name = "category_id", referencedColumnName = "category_id"))
private List<Category> categories;
Класс категории:
@Entity
public class Category {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long category_id;
private String name;
@ManyToMany(mappedBy = "categories")
private List<Book> books;
Репозиторий JPA с методом, использующим созданный граф объектов:
@Component
@Repository
public interface BookJpaRepository extends JpaRepository<Book, Long> {
@Override
@EntityGraph(value = "Book.summary", type = EntityGraph.EntityGraphType.FETCH)
List<Book> findAll(); }
Использование в контроллере REST:
@RequestMapping("/books")
@ResponseBody
public List<Book> getBooksSummary() {
return bookJpaRepository.findAll();
}
После запуска Spring Boot (mvn spring-boot:run) и перехода к http://localhost:8080/books книгам отображаются, но с соответствующими категориями (и возникает исключение из-за бесконечной рекурсии: книги -> категории -> книги -> категории -> ...).
Тот же код в тесте (запущенный с помощью SpringJUnit4ClassRunner) работает, как и ожидалось, и граф объектов распознается правильно. Например, приведенный ниже код не отображает категории, потому что, как и ожидалось, инициализация отложена:
@Test
public void testEntityGraph() {
List<Book> all = bookJpaRepository.findAll();
System.out.println(all.get(0).getCategories());
}
Любые предложения, как заставить графы сущностей работать, когда приложение работает в Spring Boot?
LAZY
fetchType приведет к ее загрузке. Я считаю, что когда вы вызываете методfindAll
на своем контроллере, он получает всю сущность, включая свойства, помеченные какLAZY
. Именно сериализация вызывает загрузкуcategories
. - person Rae Burawes   schedule 29.07.2016