2014-11-27 2 views
7

Я начал использовать новую функцию графа объектов в JPA 2.1, чтобы указать коллекции Lazy, которые необходимо загрузить. Рассмотрим следующие классы:JPA 2.1 График объектов возвращает дублированные результаты

@Entity 
@NamedQueries({ 
    @NamedQuery(name="findWithFilterAttr","select a from A a where a.filterAttribute like :filter") 
}) 
@NamedEntityGraphs({ 
@NamedEntityGraph(name = "graph.childs", attributeNodes = @NamedAttributeNode("childs"))}) 
public class A{ 
    @Id 
    private long id; 
    @OneToMany(mappedBy="parent") 
    private List<B> childs; 
    private String filterAttribute; 
} 
@Entity 
public class B{ 
    @Id 
    private long id; 
    @ManyToOne 
    private A parent; 
} 

Когда я выполнить именованный запрос, чтобы получить список из субъектов с лицом графа намеком я получаю коллекцию повторен лиц. Как я могу загрузить объекты A только один раз.

Я использую:

  • Hibernate 4.3.5
  • Wildfly 8.1

ответ

5

я, наконец, решил это, я добавил DISTINCT к именованного запроса и все теперь работает .... Ошибка была вызвана тем, что, когда поставщик JPA находит подсказку на основе сущности, он создает LEFT JOIN с дочерней таблицей. Оригинал запроса без сущности графа:

11:55:28,950 INFO [stdout] (default task-23) Hibernate: 
11:55:28,950 INFO [stdout] (default task-23)  select 
11:55:28,951 INFO [stdout] (default task-23)   entitya0_.id as id1_0_0_, 
11:55:28,951 INFO [stdout] (default task-23)   childs1_.id as id1_1_1_, 
11:55:28,951 INFO [stdout] (default task-23)   entitya0_.filter as filter2_0_0_, 
11:55:28,951 INFO [stdout] (default task-23)   childs1_.parent_id as parent_i2_1_1_, 
11:55:28,951 INFO [stdout] (default task-23)   childs1_.parent_id as parent_i2_0_0__, 
11:55:28,951 INFO [stdout] (default task-23)   childs1_.id as id1_1_0__ 
11:55:28,951 INFO [stdout] (default task-23)  from 
11:55:28,951 INFO [stdout] (default task-23)   EntityA entitya0_ 
11:55:28,951 INFO [stdout] (default task-23)  left outer join 
11:55:28,952 INFO [stdout] (default task-23)   EntityB childs1_ 
11:55:28,952 INFO [stdout] (default task-23)    on entitya0_.id=childs1_.parent_id 
11:55:28,952 INFO [stdout] (default task-23)  where 
11:55:28,952 INFO [stdout] (default task-23)   entitya0_.filter like ? 

запросов с отчетливым и сущности графа:

11:57:25,051 INFO [stdout] (default task-24) Hibernate: 
11:57:25,052 INFO [stdout] (default task-24)  select 
11:57:25,052 INFO [stdout] (default task-24)   distinct entitya0_.id as id1_0_0_, 
11:57:25,052 INFO [stdout] (default task-24)   childs1_.id as id1_1_1_, 
11:57:25,052 INFO [stdout] (default task-24)   entitya0_.filter as filter2_0_0_, 
11:57:25,052 INFO [stdout] (default task-24)   childs1_.parent_id as parent_i2_1_1_, 
11:57:25,052 INFO [stdout] (default task-24)   childs1_.parent_id as parent_i2_0_0__, 
11:57:25,052 INFO [stdout] (default task-24)   childs1_.id as id1_1_0__ 
11:57:25,052 INFO [stdout] (default task-24)  from 
11:57:25,052 INFO [stdout] (default task-24)   EntityA entitya0_ 
11:57:25,052 INFO [stdout] (default task-24)  left outer join 
11:57:25,052 INFO [stdout] (default task-24)   EntityB childs1_ 
11:57:25,052 INFO [stdout] (default task-24)    on entitya0_.id=childs1_.parent_id 
11:57:25,052 INFO [stdout] (default task-24)  where 
11:57:25,052 INFO [stdout] (default task-24)   entitya0_.filter like ? 
+0

Спасибо большое за отправляя свое решение! Это также работает с JPA с именем «Запросы». см.: [this SO post] (http://stackoverflow.com/questions/24314829/named-entity-graph-joins-results-need-distinct-option) – muri

0

Небольшое дополнение.

У меня была такая же проблема, как и вы. Я думаю, что это поведение неожиданно и может быть недостатком в спящем режиме. Не нужно указывать distinct, как в случае с выборками, непосредственно указанными в запросе JPQL.

Ваше решение скорее обходное решение из-за ограничений реализации. При проверке кода (вычисление needsDistincting флага в методе list(), доступный на grepcode), есть два решения:

  • добавляющие пределы запроса
  • с использованием отчетливый
+0

Примечание: это чистая проблема спящего режима, без Wildfly здесь , Вы должны удалить тег. – Jidehem

Смежные вопросы