Hibernate zeroToOne - PullRequest
       21

Hibernate zeroToOne

1 голос
/ 17 августа 2010

Я пытаюсь установить отношения между двумя объектами, которые были бы равны нулю. То есть Родитель может быть сохранен без связанной дочерней сущности, а также вместе с ассоциированным дочерним объектом. Ниже приведены 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 (Child)

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 в столбце идентификатора ребенка .


Одним из решений может быть не использование PrimaryKeyJoinColumn, а использование определенного JoinColumn, но это добавляет ненужный столбец в мою существующую таблицу.


Кто-нибудь сталкивался с такой проблемой? Если да, любые указатели были бы очень полезны.

Ответы [ 2 ]

1 голос
/ 18 августа 2010

Наконец-то я заработал благодаря Паскалю и некоторому поиску с моей стороны. По-видимому, я не могу использовать генератор родного ключа для таких отношений, где родитель может существовать без дочернего (опционально = 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 в настоящее время не поддерживает это (или любые аналогично) аннотация.

В любом случае, помогает пройти через такие случаи: -)

1 голос
/ 17 августа 2010

У меня есть сценарий, в котором я хотел бы сохранить родительский объект (Сотрудник) без связанного объекта EmpInfo.

Атрибут optional OneToOne равен true по умолчанию, это то, что вам нужно.

Однако вы как-то неправильно используете @PrimaryKeyJoinColumn здесь (ну, на самом деле, это зависит от того, чего вы действительно хотите достичь, но ваша текущая комбинация аннотаций не верна).

ЕСЛИ вы хотите отобразить OneToOne с общим первичным ключом , используйте @PrimaryKeyJoinColumn.Но в этом случае не используйте GeneratedValue на EmployeeInfo и устанавливайте идентификатор вручную или, если вы не хотите устанавливать его вручную, используйте генератор Hibernate foreign, которыйЯ уже упоминал в ваш предыдущий вопрос .Также проверьте соответствующий вопрос, упомянутый ниже.

И ЕСЛИ вы не хотите использовать общий первичный ключ (как в вашем текущем коде, так как вы пытаетесь получить идентификатор, сгенерированныйбазы данных), тогда не используйте PrimaryKeyJoinColumn.

Вам нужно сделать выбор.

Ссылки

  • JPA 1.0 спецификация:
    • 9.1.32 PrimaryKeyJoinColumn Аннотация

Смежный вопрос

...