СПД гибернации один-к-одному отношения
у меня есть отношения один-к-одному, но hibernatetool жалуется при создании схемы. Вот пример, который показывает проблему:
@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-это собственная сторона, поэтому человек использует mappedBy чтобы указать имя атрибута "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)
...
есть идеи, почему? Я делаю что-то неправильно или это ошибка спящего режима?
7 ответов:
JPA не позволяет @Id аннотации OneToOne или ManyToOne сопоставление. То, что вы пытаетесь сделать,-это ассоциация один к одному с общим первичным ключом. Самый простой случай-однонаправленный один к одному с общим ключом:
@Entity public class Person { @Id private int id; @OneToOne @PrimaryKeyJoinColumn private OtherInfo otherInfo; rest of attributes ... }основная проблема заключается в том, что JPA не поддерживает генерацию общего первичного ключа в OtherInfo сущности. Классическая книга Персистентности Java с Hibernate by Bauer and King дает следующее решение проблемы с помощью расширения 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 ... }Также см. здесь.
Это тоже должно работать с использованием аннотации JPA 2.0 @MapsId вместо GenericGenerator Hibernate:
@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.
вам просто нужно добавить
@JoinColumn(name="column_name")для размещения объекта связи . имя_столбца-имя столбца базы данных в таблице person.@Entity public class Person { @Id public int id; @OneToOne @JoinColumn(name="other_info") public OtherInfo otherInfo; rest of attributes ... }человек имеет отношения один к одному с OtherInfo: mappedBy=" var_name " var_name-это имя переменной для класса otherInfo в Person.
@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, которые, похоже, требуют, чтобы вы указали, как ассоциация wokrs.
У меня есть лучший способ сделать это:
@Entity public class Person { @OneToOne(cascade={javax.persistence.CascadeType.ALL}) @JoinColumn(name = "`Id_OtherInfo`") public OtherInfo getOtherInfo() { return otherInfo; } }вот и все
попробуй такое
@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 ... }
Comments