jpa hibernate @OneToOne @JoinColumn referencedColumnName 被忽略

leo*_*cci 6 java entity hibernate jpa

我在对与另一个实体具有一对一关系的实体执行 jpql 查询时遇到意外行为。关键点是关系是从根实体的主键到目标实体的不是 ID 的字段。

这是示例:

// root entity
@Entity
@Table(name = "PERSON")

public class Person {

    @Id
    @Column(name = "PERSON_ID")
    private long id;

    private String name;

    @OneToOne(optional = false)
    @JoinColumn(name = "PERSON_ID", referencedColumnName = "PERSON_ID", insertable = false, updatable = false, unique = true)
    private Address mainAddress;
    ...
}
// referenced entity
@Entity
@Table(name = "ADDRESS")
public class Address {

    @Id
    @Column(name = "ADDRESS_ID")
    private long id;

    @Column(name = "PERSON_ID")
    private long personId;
    ...
}
Run Code Online (Sandbox Code Playgroud)

以下 jpql 查询:

select p from Person p left join fetch p.mainAddress
Run Code Online (Sandbox Code Playgroud)

生成以下 ORACLE SQL 查询:

SELECT ... FROM PERSON p LEFT OUTER JOIN ADDRESS a ON p.PERSON_ID = a.ADDRESS_ID
Run Code Online (Sandbox Code Playgroud)

虽然我期望:

SELECT ... FROM PERSON p LEFT OUTER JOIN ADDRESS a ON p.PERSON_ID = a.PERSON_ID
Run Code Online (Sandbox Code Playgroud)

基本上,referencedColumnName = "PERSON_ID"属性的属性将被忽略,并在主键上执行连接。

有人可以解释我为什么吗?

Ala*_*Hay 5

按照@OneToOne原样映射,外键将在 Person 表中,即。Person 表(如果您没有在 @JoinColumn 注释中指定 person_id)应该有一个 FK 列“address_id”。

形成您期望生成的 SQL 的样子,看起来您希望 FK 位于地址表中,即地址具有 FK 列 person_id。您可以通过以下方式执行此操作:

@Entity
@Table(name = "PERSON")

public class Person {

    @Id
    @Column(name = "PERSON_ID")
    private long id;

    private String name;

    @OneToOne(mappedBy = "person")
    private Address mainAddress;

}


@Entity
@Table(name = "ADDRESS")
public class Address {

    @Id
    @Column(name = "ADDRESS_ID")
    private long id;

    @OneToOne(optional = false)
    @JoinColumn(name = "PERSON_ID", insertable = false, updatable = false, unique = true)
    private Person person;

}
Run Code Online (Sandbox Code Playgroud)