JPAhibernate一对一的关系
我有一对一的关系,但是hibernatetool在生成模式时抱怨。 这是一个显示问题的例子:
@Entity public class Person { @Id public int id; @OneToOne public OtherInfo otherInfo; rest of attributes ... }
Person与OtherInfo有一对一的关系:
@Entity public class OtherInfo { @Id @OneToOne(mappedBy="otherInfo") public Person person; rest of attributes ... }
人是拥有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) ...
任何想法为什么? 我是一个做错了什么,或者这是一个Hibernate的错误?
JPA不允许在OneToOne或ManyToOne映射上使用@Id批注。 你要做的是与共享主键一对一的实体关联。 最简单的情况是使用共享密钥的单向一对一:
@Entity public class Person { @Id private int id; @OneToOne @PrimaryKeyJoinColumn private OtherInfo otherInfo; rest of attributes ... }
与此相关的主要问题是JPA不支持在OtherInfo实体中共享主键生成。 鲍尔和金的经典着作“ Java Persistence with Hibernate”给出了使用Hibernate扩展的问题的以下解决scheme:
@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 ... }
另外,看到这里 。
这应该也使用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 ... }
在5.1.2.2.7节的Hibernate 4.1文档中有更多的细节。
你只需要添加@JoinColumn(name="column_name")
到主机实体关系。 column_name是人员表中的数据库列名称。
@Entity public class Person { @Id public int id; @OneToOne @JoinColumn(name="other_info") public OtherInfo otherInfo; rest of attributes ... }
Person与OtherInfo具有一对一的关系:mappedBy =“var_name”var_name是Person类中otherInfo的variables名称。
@Entity public class OtherInfo { @Id @OneToOne(mappedBy="otherInfo") public Person person; rest of attributes ... }
我认为你仍然需要在OtherInfo类的主键属性。
@Entity public class OtherInfo { @Id public int id; @OneToOne(mappedBy="otherInfo") public Person person; rest of attributes ... }
另外,您可能需要将@PrimaryKeyJoinColumn注释添加到映射的另一侧。 我知道Hibernate默认使用这个。 但是,我没有使用JPA注释,这似乎要求你指定如何关联的工具。
我有一个更好的方式来做到这一点:
@Entity public class Person { @OneToOne(cascade={javax.persistence.CascadeType.ALL}) @JoinColumn(name = "`Id_OtherInfo`") public OtherInfo getOtherInfo() { return otherInfo; } }
就这样
我不确定你可以在Hibernate中使用关系作为Id / PrimaryKey。
尝试这个
@Entity @Table(name="tblperson") public class Person { public int id; public OtherInfo otherInfo; @Id //Here Id is autogenerated @Column(name="id") @GeneratedValue(strategy=GenerationType.AUTO) public int getId() { return id; } public void setId(int id) { this.id = id; } @OneToOne(cascade = CascadeType.ALL,targetEntity=OtherInfo.class) @JoinColumn(name="otherInfo_id") //there should be a column otherInfo_id in Person public OtherInfo getOtherInfo() { return otherInfo; } public void setOtherInfo(OtherInfo otherInfo) { this.otherInfo= otherInfo; } rest of attributes ... } @Entity @Table(name="tblotherInfo") public class OtherInfo { private int id; private Person person; @Id @Column(name="id") @GeneratedValue(strategy=GenerationType.AUTO) public Long getId() { return id; } public void setId(Long id) { this.id = id; } @OneToOne(mappedBy="OtherInfo",targetEntity=Person.class) public College getPerson() { return person; } public void setPerson(Person person) { this.person = person; } rest of attributes ... }