FetchJoin далекой сущности - PullRequest
0 голосов
/ 22 января 2019

У меня следующая ситуация:

Foo.java

@Entity
public class Foo {

    @Id
    private long id;

    @ManyToOne
    @JoinColumn(name = "barId", insertable = false, updatable = false)
    private Bar bar;

}

Bar.java

@Entity
public class Bar {

    @Id
    private long id;

    @OneToMany(mappedBy = "compositeId.barId")
    private HashSet<Xpto> xptos;
}

Xpto.java

@Entity
public class Xpto {

    @EmbeddedId
    private XptoId compositeId

    @MapsId("axisRailroadId")
    @ManyToOne
    @JoinColumn(name = "barId")
    private Bar bar;
}

@Embeddable
class XptoId {

    @Column(name = "barId")
    private long barId;

    @Column(name = "stringKey")
    private String someStringKey;
}

И у меня есть запрос, в котором я выбираю Foo s и использую свойства Xpto. Если мне нравится:

QFoo qFoo = QFoo.foo;
List<Foo> foos = query.from(foo).fetch();

// Use the foos list

Это работает, но я вижу в своем журнале, что Hibernate обращается к базе данных каждый раз, когда мне нужно Bar или Xpto от объекта Foo. Пытаясь сделать все это в одном запросе с Joins, я попытался:

  • Установка типов выборки на EAGER - Это не сработало, тот же результат (я знаю, что это плохо в любом случае)
  • Использование Hibernate @Fetch(FetchMode.JOIN) - Это не работает, ничего не меняет ... Может быть, потому что QueryDSL или Spring-Data влияют на на это ...?

Одна вещь, которую я думаю, сработает, это создание соединений вручную с помощью QueryDSL. Но я застрял на этом. Я пытаюсь:

QFoo qFoo = QFoo.foo;
List<Foo> foos = query.from(qFoo)
    .leftJoin(foo.bar).fetchJoin()
    .leftJoin(foo.bar.xptos).fetchJoin()
.fetch();

Выдает исключение, например:

org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list 
[FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=Xpto,role=com.example.Bar.xptos,tableName=xpto,tableAlias=... 
select foo ↵from com.example.Foo foo left join fetch foo.bar left join fetch foo.bar.xptos as xptos]

Я тоже пробовал как:

QFoo qFoo = QFoo.foo;
QXpto qXpto = QXpto.xpto;
List<Foo> foos = query.from(qFoo)
    .leftJoin(foo.bar).fetchJoin()
    .leftJoin(qXpto).on(qFoo.barId.eq(qXpto.compositeId.barId)).fetchJoin()
.fetch();

Это хорошо работает, и я вижу следующий запрос:

Hibernate:
    /* select
        foo
    from
        Foo foo
    left join
        fetch foo.bar
    left join
        fetch Xpto xpto with foo.barId = xpto.compositeId.barId

Но дело в том, что когда я получаю доступ к списку Foos, я все равно вижу, что Hibernate запрашивает XPTOs. Как будто он не узнал, что он уже был извлечен из базы данных.

Есть идеи, как заставить это работать?

...