Связь JPA Hibernate «один-к-одному»
У меня есть отношения «один к одному», но 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» в Person.
- Учебное пособие по процедурам JPA
- JPA: как преобразовать собственный набор результатов запроса в коллекцию classов POJO
- В чем разница между @JoinColumn и mappedBy при использовании ассоциации JPA @OneToMany
- Проблема спящего режима - «Использование @OneToMany или @ManyToMany для таргетинга на немаркированный class»
- Я обнаружил, что JPA, или, похоже, не поощряет шаблон DAO
Я получаю следующую ошибку при использовании 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.(SchemaExport.java:128) ...
Любая идея почему? Я что-то делаю неправильно или это ошибка Hibernate?
- Борьба за понимание правильного использования EntityManager
- Ошибка проверки: значение недействительно
- Использование дженериков в репозиториях Spring Data JPA
- Разница между «jta-datasource» и «ресурсо-местным» источником данных?
- Совместное использование сущностей между модулями App Engine
- Когда JPA устанавливает @GeneratedValue @Id
- Hibernate - @ElementCollection - странное поведение удаления / вставки
- Спящий режим, весна, JPS и изоляция - индивидуальная изоляция не поддерживается
JPA не разрешает аннотацию @Id для отображения OneToOne или ManyToOne . То, что вы пытаетесь сделать, – это взаимно однозначная ассоциация сущностей с общим первичным ключом . Самый простой случай – однонаправленный однонаправленный с общим ключом:
@Entity public class Person { @Id private int id; @OneToOne @PrimaryKeyJoinColumn private OtherInfo otherInfo; rest of attributes ... }
Основная проблема заключается в том, что JPA не поддерживает поддержку генерации общего первичного ключа в объекте OtherInfo . Классическая книга Java Persistence with Hibernate by Bauer и 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 annotations вместо 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.
Вам просто нужно добавить @JoinColumn(name="column_name")
в отношение Host Entity. column_name – имя столбца базы данных в личной таблице.
@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 в classе Person.
@Entity public class OtherInfo { @Id @OneToOne(mappedBy="otherInfo") public Person person; rest of attributes ... }
Я думаю, что вам еще нужно свойство первичного ключа в classе OtherInfo.
@Entity public class OtherInfo { @Id public int id; @OneToOne(mappedBy="otherInfo") public Person person; rest of attributes ... }
Кроме того, вам может понадобиться добавить аннотацию @PrimaryKeyJoinColumn на другую сторону отображения. Я знаю, что Hibernate использует это по умолчанию. Но тогда я не использовал annotations JPA, которые, как вам кажется, требуют указать, как ассоциация wokrs.
У меня есть лучший способ сделать это:
@Entity public class Person { @OneToOne(cascade={javax.persistence.CascadeType.ALL}) @JoinColumn(name = "`Id_OtherInfo`") public OtherInfo getOtherInfo() { return otherInfo; } }
Это все
Я не уверен, что вы можете использовать отношения как Id / PrimaryKey в Hibernate.
Попробуй это
@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 ... }