У меня есть сущность с двумя списками дочерних объектов. При вызове EntityManager.find() он возвращает дубликаты на основе умножения двух списков.JPA - метод поиска EntityManager возвращает дубликаты
Я использую Spring, Jackson и JPA с Hibernate и SQL Server.
При тестировании с одним из родителей, который имеет N элементы первого и M второго дочернего объекта всегда возвращает N * M элементы обоих образований.
В приведенном ниже примере есть задачи и комментарии и JPA возвращает для обоих списков. (5 копий списка задач и 3 копии списка комментариев)
Выход из контроллера:
Comments 15
Tasks 15
И остальная часть кода находится ниже.
controller.java
@RequestMapping(method = RequestMethod.GET)
public String listAll(Model model) {
Goal goal = new Goal();
goal = service.getGoalById(25);
System.out.println("Comments " + goal.getComments().size());
System.out.println("Tasks " + goal.getTasks().size());
return "home";
}
service.java
@Transactional
public Goal getGoalById(int goalId) {
Goal goal = em.find(Goal.class, goalId);
return goal;
}
goal.java
@Entity
@Table(name = "goal")
public class Goal {
@Id
@GeneratedValue
private int id;
@JsonManagedReference
@OneToMany(mappedBy = "tasksGoal", cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
private List<Task> projectTasks = new ArrayList<Task>();
@JsonManagedReference
@OneToMany(mappedBy = "commentsGoal", cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
private List<Comment> goalComments = new ArrayList<Comment>();
...
}
task.java
@Entity
@Table(name="projectTask")
public class Task {
@Id
@GeneratedValue
private int id;
@JsonBackReference
@ManyToOne (fetch = FetchType.LAZY)
@JoinColumn(name = "task_goal_id")
private Goal tasksGoal;
...
}
comment.java
@Entity
@Table (name="goalComment")
public class Comment {
@Id
@GeneratedValue
private int id;
@JsonBackReference
@ManyToOne (fetch = FetchType.LAZY)
@JoinColumn(name = "goal_id")
private Goal commentsGoal;
...
}
persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="persistenceUnit"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServer2008Dialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" />
<property name="hibernate.connection.charSet" value="UTF-8" />
<!-- Hibernate prints SQL -->
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
Возможный дубликат [Hibernate Criteria возвращает несколько раз несколько раз с FetchType.EAGER] (http://stackoverflow.com/questions/1995080/hibernate-criteria-returns-children-multiple-times-with-fetchtype-eager) –
Помечено как дубликат. Возможные быстрые исправления. Либо удалите Eager fetch из ассоциаций, либо измените коллекции из списка в Set. –
Большое спасибо за быстрое исправление, я использовал Set. Но я все еще думаю, что этот вопрос не дублируется. Я не использую HQL и почему-то вы ожидаете, что JPA обработает или сообщит вам об этих ошибках при использовании метода find. Я полностью понимаю, почему это происходит, но не думайте, что легко найти ответ. В целом большое спасибо! :) –