2013-04-20 14 views
1

У меня есть отношения «один ко многим родитель-ребенок», и я хочу, чтобы все это продолжалось один раз. Проблема, с которой я сталкиваюсь, состоит в том, что у ребенка есть идентификатор родителя, но в момент настойчивости он не может получить этот идентификатор с момента его создания. Вот настройки у меня до сих пор:Генерация идентификатора родителя в персистентности родителя-ребенка

public class Parent 
{ 
    @Id 
    @GeneratedValue(generator = "parent-id-gen") 
    @GenericGenerator(name = "parent-id-gen", strategy = "increment") 
    @Column(name = "id", nullable = false) 
    private long ID; 

    // some other fields 

    @OneToMany(orphanRemoval = true, cascade = CascadeType.ALL) 
    @JoinColumn(name = "parent_id") 
    private List<Child> children; 
} 

public class Child 
{ 
    @Id 
    @GeneratedValue(generator = "child-id-gen") 
    @GenericGenerator(name = "child-id-gen", strategy = "increment") 
    @Column(name = "id", nullable = false) 
    private long ID; 

    @Column(name = "parent_id", nullable = false) 
    private long parentID; 

    // some other fields 
} 

база данных (PostgreSQL) выглядит следующим образом, если это имеет значение:

CREATE TABLE parent 
(
    id integer NOT NULL, 
    ... other fields, 
    PRIMARY KEY (id) 
); 

CREATE TABLE child 
(
    id integer NOT NULL, 
    parent_id integer NOT NULL, 
    ... other fields, 
    PRIMARY KEY (id), 
    UNIQUE (parent_id, ... other fields) 
); 

Я хочу сделать только один org.hibernate.Session.saveOrUpdate(parentObject), но терпит неудачу мой уникальный ключ в дочерней таблице, потому что parentID устанавливается равным 0, а не сгенерированным идентификатором родительского.

Есть ли способ сделать это?

Я думаю, что сначала вставляет Hibernate, затем обновляет дочерний элемент родительским идентификатором, поэтому нет возможности сделать это, поскольку база данных в настоящее время определена. Мне, вероятно, придется удалить уникальный ключ в результате, что является неудачным ... если есть способ обойти это, дайте мне знать!

Редактировать: Добавлена ​​информация о БД, поскольку она, вероятно, имеет значение.

ответ

1

Идея Hibernate заключается в том, что ваши классы моделей абстрагируются от идентификационных материалов между отношениями. Значение private long parentID может быть изменено на private Parent parent. Это позволит hibernate знать, как управлять им, и если вам нужен идентификатор родителя, вы можете сделать что-то вроде child.getParent().getId()

+0

. Меня интересует такой подход: (1) как Джексон обрабатывает такие круговые отношения при сериализации к JSON? и (2) как определить отношения '@ OneToMany', если нет возможности' @ JoinColumn'? Является ли Hibernate достаточно умным, чтобы знать, что объект «Child» имеет ссылку на «Parent», поэтому нет необходимости определять '@ JoinColumn' вообще? Похоже, мне, вероятно, нужно узнать о том, как JPA «предполагается» использовать ... – Depressio

+0

Взгляните на [javadoc] (http://docs.oracle.com/javaee/6/api/javax/persistence/OneToMany .html), вы можете использовать атрибут mappedBy annotation, чтобы определить, что Child является владельцем этого отношения. [этот вопрос может помочь понять больше] (http://stackoverflow.com/a/10827044/1001027) –

+0

Я сбросил '@ JoinColumn' и добавил' mappedBy' в аннотацию '@ OneToMany', затем пришлось добавить' @ OneToOne аннотация для ребенка. Интересно, что Hibernate достаточно умен, чтобы ожидать столбец «parent_id» в дочерней таблице. Тем не менее, я не смог заставить его фактически заполнить столбец (мне пришлось сделать его нулевым в БД). Полагаю, это совсем другая проблема. – Depressio

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