Hibernate zeroToOne
Я пытаюсь установить отношения между двумя объектами, которые были бы равны нулю. Таким образом, Родитель может быть сохранен без связанной дочерней сущности, а также вместе с ассоциированным дочерним объектом. Ниже приведены 2 класса сущностей...
Сотрудник (родитель)
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name="EMP_NAME")
private String name;
@PrimaryKeyJoinColumn
@OneToOne(cascade = {CascadeType.ALL})
private EmployeeInfo info;
@Column(name="EMP_ENUM")
private Integer enumId;
EmployeeInfo (ребенок)
public class EmployeeInfo {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(name="EMPLOYEE_EMAIL")
private String email;
При таком типе столбца отношения и идентификатора единственной таблицы Parent (Employee), установленной в AUTO INCREMENT в MySql DB, проблема заключается в том, что при сохранении графа объекта Parent->Child я получаю следующее исключение
org.springframework.orm.hibernate3.HibernateJdbcException: JDBC exception on Hibernate data access: SQLException for SQL [insert into EMP_INFO
Caused by: java.sql.SQLException: Field 'id' doesn't have a default value
Я попытался установить для свойства Id дочерней таблицы значение AUTO INCREMENT в БД, и сохранение такого графа объектов Parent->Child успешно. Однако описанная здесь проблема возникает, потому что у меня есть сценарий, в котором я хотел бы сохранить родительский (Employee) объект без связанного объекта EmpInfo и, следовательно, НЕ хочу иметь AUTO INCREMENT в столбце id дочернего элемента.
Одним из решений может быть не использование PrimaryKeyJoinColumn, а использование определенного JoinColumn, но это добавляет ненужный столбец в мою существующую таблицу.
Кто-нибудь сталкивался с такой проблемой? Если да, любые указатели были бы очень полезны.
2 ответа
Наконец-то я заработал, благодаря Паскалю и некоторому поиску с моей стороны. По-видимому, я не могу использовать генератор родного ключа для таких отношений, где родитель может существовать без дочернего (необязательно = true). В конечном итоге сработало следующее: у меня не было необходимости иметь дело с аннотацией, специфичной для Hibernate (@GenericGenerator), а также нужно было работать с двунаправленными отношениями вместо однонаправленных, которые я хотел.
Employee (Parent) class remains unchanged as above. It has AUTO INCREMENT on the Id column.
Что касается дочернего класса (EmployeeInfo), он изменился на следующий, и снова БЕЗ установки AUTO INCREMENT в столбце Id.
@Table(name="EMP_INFO")
@Entity
public class EmployeeInfo {
@Id
@GeneratedValue(generator="foreign")
@GenericGenerator(name="foreign", strategy = "foreign", parameters={
@Parameter(name="property", value="verifInfo")})
private Long id;
@OneToOne(optional=false)
@JoinColumn (name="id")
private Employee emp;
@Column(name="EMPLOYEE_EMAIL")
private String email;
Это помогло мне достичь того, чего я хотел, но с другой стороны, GenericGenerator - это не аннотация JPA, а спящий режим, и, к сожалению, на данный момент я вынужден с этим справиться, потому что JPA в настоящее время не поддерживает эту (или любую аналогичную) аннотацию.,
Во всяком случае, это помогает пройти через такие случаи:-)
У меня есть сценарий, в котором я хотел бы сохранить родительский объект (сотрудник) без связанного объекта EmpInfo.
optional
атрибут OneToOne
является true
по умолчанию, это то, что вы хотите.
Тем не менее, вы как-то неправильно используете @PrimaryKeyJoinColumn
здесь (ну, на самом деле это зависит от того, чего вы действительно хотите достичь, но текущая комбинация аннотаций неверна).
Если вы хотите отобразить OneToOne
с общим первичным ключом, используйте @PrimaryKeyJoinColumn
, Но в этом случае не используйте GeneratedValue
на EmployeeInfo
и установите идентификатор вручную или, если вы не хотите устанавливать его вручную, используйте специальный Hibernateforeign
Генератор, который я уже упоминал в вашем предыдущем вопросе. Проверьте также связанный вопрос, упомянутый ниже.
И если вы не хотите использовать общий первичный ключ (как в текущем коде, поскольку вы пытаетесь получить идентификатор, сгенерированный базой данных), то не используйте PrimaryKeyJoinColumn
,
Вы должны сделать выбор.
Рекомендации
- Спецификация JPA 1.0:
- 9.1.32
PrimaryKeyJoinColumn
аннотирование
- 9.1.32