且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

JPA休眠一对一关系

更新时间:2022-10-29 23:13:56

JPA不允许 @Id ManyToOne 映射的注释。您试图做的是使用共享主键的一对一实体关联。最简单的情况是单向一对一共享密钥:

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

@OneToOne
@PrimaryKeyJoinColumn
私有OtherInfo otherInfo;

其余属性...
}

主要问题在于JPA不支持在 OtherInfo 实体***享主键生成。经典书籍 Bauer和King提供的Hibernate Java持久化给出了以下解决方案Hibernate扩展:

  @Entity 
public class OtherInfo {
@Id @GeneratedValue(generator =customForeignGenerator )
@ org.hibernate.annotations.GenericGenerator(
name =customForeignGenerator,
strategy =foreign,
parameters = @Parameter(name =property,值=人)

私人长ID;

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

其余属性...
}

另外,请参阅此处


I have a one-to-one relationship but hibernatetool complains when generating the schema. Here's an example that shows the problem:

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

    @OneToOne
    public OtherInfo otherInfo;

    rest of attributes ...
}

Person has a one-to-one relationship with OtherInfo:

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

    rest of attributes ...
}

Person is owning side of OtherInfo. OtherInfo is the owned side so person uses mappedBy to specify the attribute name "otherInfo" in Person.

I get the following error when using hibernatetool to generate the database schema:

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)
        ...

Any idea why? Am I a doing something wrong or is this a Hibernate bug?

JPA doesn't allow the @Id annotation on a OneToOne or ManyToOne mapping. What you are trying to do is one-to-one entity association with shared primary key. The simplest case is unidirectional one-to-one with shared key:

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

    @OneToOne
    @PrimaryKeyJoinColumn
    private OtherInfo otherInfo;

    rest of attributes ...
}

The main problem with this is that JPA provides no support for shared primary key generation in OtherInfo entity. The classic book Java Persistence with Hibernate by Bauer and King gives the following solution to the problem using Hibernate extension:

@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 ...
}

Also, see here.