Hibernate двунаправленный @ManyToOne, обновление не владеющей стороны не работает - PullRequest
3 голосов
/ 28 марта 2011

У меня действительно простая настройка, чтобы опробовать двунаправленное отображение с аннотациями:

@Entity
public class TypeA extends AbstractModel<TypeA> {

    @Id
    @GeneratedValue
    private int id;

    @OneToMany(mappedBy="a")
    private Collection<TypeB> bs;

    // Getters & Setters ... 
}

и

@Entity
public class TypeB extends AbstractModel<TypeB> {

    private static final long serialVersionUID = -3526384868922938604L;

    @Id
    @GeneratedValue
    private int id;

    @ManyToOne()
    @JoinColumn(name="a_id")
    private TypeA a;
}

Когда я устанавливаю свойство TypeA.bs, это не влияет на отображение, хотя и должно. Смотрите следующий пример:

TypeB b = new TypeB();
this.typeBDao.save(b);

TypeA a = new TypeA();
a.setBs(ListUtils.createList(b));

System.out.println(a.getBs()); // output: [TypeB@25fe4d40]

this.typeADao.save(a);

System.out.println(a.getBs()); // output: [TypeB@25fe4d40]

this.typeADao.refresh(a);

System.out.println(a.getBs()); // output: []

this.typeBDao.refresh(b);
System.out.println(b.getA()); // output: null

Если отображение двунаправленное, коллекция должна быть заполнена, а свойство a of b должно быть обновлено, но это не так. Есть идеи?

Редактировать Спасибо за помощь, ребята, теперь я понял!

Ответы [ 3 ]

8 голосов
/ 28 марта 2011

Для согласованной модели предметной области вы всегда должны устанавливать обе стороны отношения следующим образом:

TypeB b = new TypeB();

TypeA a = new TypeA();
a.setBs(ListUtils.createList(b));
b.setA(a);   

this.typeBDao.save(b);
this.typeADao.save(a);

Когда ваши объекты находятся в несовместимом состоянии, JPA всегда будет хранить значения в соответствии с состоянием объекта на стороне-владельце отношения JPA. В этом случае TypeB владеет отношением к TypeA. Таким образом, если объект TypeB не имеет ссылки на TypeA, JPA предполагает, что отношение не определено.

6 голосов
/ 28 марта 2011

Это способ, которым он должен работать: сторона-владелец - это та, которая владеет отношениями и отвечает за управление ими в базе данных.Это обязанность разработчика (т.е. ваша ответственность), чтобы убедиться, что ваш объектный граф всегда согласован: если одна сторона отношения изменена, то другая сторона также должна быть изменена.

Если вы не всегда делаете это, вы должны хотя бы убедиться, что изменили сторону-владельца отношений, потому что Hibernate заботится только о стороне-владельце.

1 голос
/ 28 марта 2011

Сторона-владелец - TypeB, поэтому вам необходимо позвонить setA(), так как ассоциация управляется только стороной-владельцем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...