JPA:选择实体子集不会加载@OneToOne属性

Xor*_*rty 5 java orm hibernate jpa hibernate-mapping

我有一个巨大的实体,我想加载它的子集(ID和baz属性):

@Entity
public class GiganticEntity {

    @Id Long id;

    @OneToOne(mappedBy = "giganticEntity")
    Foo foo;

    @OneToOne(mappedBy = "giganticEntity")
    Bar bar;

    @OneToOne(mappedBy = "giganticEntity")
    Baz baz;

    // default constructor + getters/setters

    public GiganticEntity(Long id, Baz baz) {
        this.id = id;
        this.baz = baz;
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用以下JPA查询,但是baz属性将为null:

"SELECT new package.GiganticEntity(ge.id, ge.baz) " +
"FROM GiganticEntity ge WHERE ge.id = 1";
Run Code Online (Sandbox Code Playgroud)

我尝试添加一个显式连接,但它也导致了null:

"SELECT new package.GiganticEntity(ge.id, b) FROM GiganticEntity ge " +
    "LEFT JOIN ge.baz as b " +
    "WHERE ge.id = 1";
Run Code Online (Sandbox Code Playgroud)

如果我只选择这样一个巨大的实体,那么一切正常(但我试图保存一些连接):

"SELECT GiganticEntity g WHERE g.id = 1";
Run Code Online (Sandbox Code Playgroud)

这可以通过JPA实现吗?我正在使用Hibernate作为其实现.

编辑:查询实际上需要LEFT JOIN,所以我需要所有巨大的参与baz-es.

Vla*_*cea 2

由于GiganticEntity与 a 具有反向的一对一关联Baz

@OneToOne(mappedBy = "giganticEntity")
Baz baz;
Run Code Online (Sandbox Code Playgroud)

这意味着 Baz 还与以下机构有关联GiganticEntity

@OneToOne
GiganticEntity giganticEntity;
Run Code Online (Sandbox Code Playgroud)

因此,查询可以变为:

select new package.GiganticEntity(g.id, b)  
from Baz b
join b.giganticEntity g
where g.id : id
Run Code Online (Sandbox Code Playgroud)

编辑

根据题目要求修改:

查询实际上需要 LEFT JOIN,所以我需要所有带有 baz-es 的巨大实体。

您可以将多个实体映射到同一个表。您将拥有GiganticEntity包含所有关联和多个实体视图:

@Entity
@Table(name="GiganticEntity")
@Immutable
public class GignaticBazViewEntity {

    @Id Long id;

    @OneToOne(mappedBy = "bar")
    Bar bar;

    @OneToOne(mappedBy = "baz")
    Baz baz;

    public GiganticEntity(Long id, Bar bar, Baz baz) {
        this.id = id;
        this.bar = bar;
        this.baz = baz;
    }
}
Run Code Online (Sandbox Code Playgroud)

查询如下:

select g
from GignaticBazViewEntity g
left join fetch g.bar
left join fetch g.baz
where g.id : id
Run Code Online (Sandbox Code Playgroud)

或者

select g
from GignaticBazViewEntity g
FETCH ALL PROPERTIES
where g.id : id
Run Code Online (Sandbox Code Playgroud)