JPA 休眠一对一关系

2022-08-31 15:51:03

我有一个一对一的关系,但休眠工具在生成架构时抱怨。下面是一个显示该问题的示例:

@Entity
public class Person {
    @Id
    public int id;

    @OneToOne
    public OtherInfo otherInfo;

    rest of attributes ...
}

人与OtherInfo有一对一的关系:

@Entity
public class OtherInfo {
    @Id
    @OneToOne(mappedBy="otherInfo")
    public Person person;

    rest of attributes ...
}

人是OtherInfo的拥有方。OtherInfo 是拥有的一方,因此用户使用在 Person 中指定属性名称“otherInfo”。mappedBy

使用hibernatetool生成数据库架构时,我收到以下错误:

org.hibernate.MappingException: Could not determine type for: Person, at table: OtherInfo, for columns: [org.hibernate.mapping.Column(person)]
        at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:292)
        at org.hibernate.mapping.SimpleValue.createIdentifierGenerator(SimpleValue.java:175)
        at org.hibernate.cfg.Configuration.iterateGenerators(Configuration.java:743)
        at org.hibernate.cfg.Configuration.generateDropSchemaScript(Configuration.java:854)
        at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:128)
        ...

任何想法为什么?我是做错了什么,还是这是一个休眠错误?


答案 1

JPA 不允许在一对一或对一映射上@Id注释。您尝试执行的操作是与共享主键进行一对一的实体关联。最简单的情况是使用共享密钥的单向一对一:

@Entity
public class Person {
    @Id
    private int id;

    @OneToOne
    @PrimaryKeyJoinColumn
    private OtherInfo otherInfo;

    rest of attributes ...
}

这样做的主要问题是JPA不支持在OtherInfo实体中生成共享主键。Bauer和King的经典著作Java Persistence with Hibernate给出了使用Hibernate扩展的问题的以下解决方案:

@Entity
public class OtherInfo {
    @Id @GeneratedValue(generator = "customForeignGenerator")
    @org.hibernate.annotations.GenericGenerator(
        name = "customForeignGenerator",
        strategy = "foreign",
        parameters = @Parameter(name = "property", value = "person")
    )
    private Long id;

    @OneToOne(mappedBy="otherInfo")
    @PrimaryKeyJoinColumn
    public Person person;

    rest of attributes ...
}

另外,请参阅此处


答案 2

这应该也可以使用JPA 2.0@MapsId注释而不是Hibernate的GenericGenerator:

@Entity
public class Person {

    @Id
    @GeneratedValue
    public int id;

    @OneToOne
    @PrimaryKeyJoinColumn
    public OtherInfo otherInfo;

    rest of attributes ...
}

@Entity
public class OtherInfo {

    @Id
    public int id;

    @MapsId
    @OneToOne
    @JoinColumn(name="id")
    public Person person;

    rest of attributes ...
}

有关此内容的更多详细信息,请参阅 Hibernate 4.1 文档第 5.1.2.2.7 节下的相关内容。


推荐