JPA Hibernate一对一的关系

Ste*_*Kuo 62 java hibernate jpa

我有一对一的关系,但hibernatetool在生成模式时抱怨.这是一个显示问题的示例:

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

    @OneToOne
    public OtherInfo otherInfo;

    rest of attributes ...
}
Run Code Online (Sandbox Code Playgroud)

Person与OtherInfo有一对一的关系:

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

    rest of attributes ...
}
Run Code Online (Sandbox Code Playgroud)

人拥有OtherInfo的一面.OtherInfo是拥有的一方,因此人们用来mappedBy在Person中指定属性名称"otherInfo".

使用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)
        ...
Run Code Online (Sandbox Code Playgroud)

知道为什么吗?我做错了什么或者这是一个Hibernate错误?

top*_*hef 85

JPA不允许在OneToOneManyToOne映射上使用@Id注释.您要做的是与共享主键的一对一实体关联.最简单的情况是使用共享密钥进行单向一对一:

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

    @OneToOne
    @PrimaryKeyJoinColumn
    private OtherInfo otherInfo;

    rest of attributes ...
}
Run Code Online (Sandbox Code Playgroud)

这个问题的主要问题是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 ...
}
Run Code Online (Sandbox Code Playgroud)

另外,请看这里.

  • 很好的答案,只是想补充一点,您可能需要在Person类中添加以下注释(我必须使事情正常工作):`@Cascade({CascadeType.ALL,CascadeType.DELETE_ORPHAN})` (3认同)

Mar*_*usz 23

这应该也可以使用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 ...
}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅第5.1.2.2.7节中的Hibernate 4.1文档.

  • 为什么在`OtherInfo`上指定`@ JoinColumn`而不是使用`@ PrimaryKeyJoinColumn`? (2认同)

Igo*_*kov 10

您只需要添加@JoinColumn(name="column_name")到Host Entity关系.column_name是person表中的数据库列名.

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

    @OneToOne
    @JoinColumn(name="other_info")
    public OtherInfo otherInfo;

    rest of attributes ...
}
Run Code Online (Sandbox Code Playgroud)

Person与OtherInfo具有一对一的关系:mappedBy ="var_name"var_name是Person类中otherInfo的变量名.

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

    rest of attributes ...
}
Run Code Online (Sandbox Code Playgroud)