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 аннотирование

Связанный вопрос

Другие вопросы по тегам