jpa hibernate @OneToOne @JoinColumn referencedColumnName被忽略

时间:2016-05-05 10:15:09

标签: java hibernate jpa entity

我在与另一个具有一对一关系的实体上执行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;
    ...
}

以下jpql查询:

select p from Person p left join fetch p.mainAddress

生成以下ORACLE SQL查询:

SELECT ... FROM PERSON p LEFT OUTER JOIN ADDRESS a ON p.PERSON_ID = a.ADDRESS_ID

虽然我期待:

SELECT ... FROM PERSON p LEFT OUTER JOIN ADDRESS a ON p.PERSON_ID = a.PERSON_ID

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

有人可以解释一下为什么?

2 个答案:

答案 0 :(得分:3)

按原样映射@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;

}

答案 1 :(得分:0)

我认为,@JoinColumn映射的@OneToOne表示指定@JoinColumn的持久性表中的连接列:Person,(与{{1}不同}})。

所以使用更简单明了的映射

@OneToMany