加入一个遥远的实体

时间:2019-01-22 17:15:59

标签: java hibernate jpa spring-data querydsl

我有以下情况:

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并使用Xpto属性。如果我喜欢:

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

// Use the foos list

它可以工作,但是每次我需要从Bar对象中获取XptoFoo时,我都在日志中看到Hibernate正在访问数据库。 尝试使用Joins在单个查询中完成所有操作,我尝试过:

  • 将获取类型设置为EAGER-没用,结果相同(我知道这还是很糟糕)
  • 使用Hibernate的@Fetch(FetchMode.JOIN)-不起作用,什么也没改变...也许是因为QueryDSL或Spring-Data is influencing在此...?

我认为将起作用的一件事是使用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。就像它不认识它已经从数据库中获取一样。

关于如何进行这项工作的任何想法?

0 个答案:

没有答案