Дочерние элементы TopLink JPA извлекают результаты во многих вызовах SQL для детей

У меня проблема с сгенерированным SQL из модели, которую мы построили с использованием JPA (TopLink) У нас есть следующие

@Entity
@Table(name = "T_TEST_A")
@Access(AccessType.FIELD)
public class TTestA implements Serializable {

@Id
@Column(name = "A_ID")
private String id;

@OneToOne
@PrimaryKeyJoinColumn
private D detail;


@OneToMany()
@JoinTable(name = "T_TEST_JOIN", joinColumns = @JoinColumn(name = "TABLE_FK"),    inverseJoinColumns = @JoinColumn(name = "B_ID"))
private List<B> childrens;
...
}

@Entity
@Table(name = "T_TEST_B")
@Access(AccessType.FIELD)
public class TTestB implements Serializable {

@Id
@Column(name = "B_ID")
private String id;

@OneToOne
@PrimaryKeyJoinColumn
private D detail;
...
}

@Entity
@Table(name = "T_TEST_D")
@Access(AccessType.FIELD)
public class D implements Serializable {

@Id
@Column(name = "D_ID")
private String id;

@OneToOne
@PrimaryKeyJoinColumn
private M moreDetail;
...
}

По сути, это отношение «один ко многим» с использованием отношения трех таблиц. Используя Criteria API, я могу получить первый уровень и все отношения «один-к-одному» (каскадные) и дочерние элементы из A, то есть A => D => M, в одном SQL с помощью fetch, но я могу ' t заставить детей B => D => M действовать так же.

Я получаю SQL-запрос, который получает A, D, M и B, но затем несколько запросов, чтобы получить B => D => M.

Вот что я делаю:

    final CriteriaBuilder cb = em.getCriteriaBuilder();
    final CriteriaQuery<A> c = cb.createQuery(A.class);
    final Root<A> a = c.from(A.class);
    a.fetch(A_.details).fetch(D_.modeDetails);
    a.fetch(A_.childrens);

    ...

Можно ли "усложнить" призывы и для детей?


person sansp00    schedule 23.09.2013    source источник


Ответы (1)


После долгой возни я заметил, что у меня есть еще одна проблема, заключающаяся в том, что запрос будет возвращать дубликаты. В итоге я использовал a.join (A_.childrens, JoinType.LEFT) .fetch (B_.details) И с помощью подсказки запроса query.setHint (QueryHints.FETCH, "t1.childrens") мне удалось удалить дубликаты и получить более глубокий уровень.

person sansp00    schedule 25.09.2013