Проблема в том, что hibernate не синхронизирует коллекции. Подробнее:
Есть класс:
public class Foo {
private int id;
private Foo parent;
private Set children;
public int getId() { return id; }
void setId(int id) { this.id = id; }
public Foo getParent() { return parent; }
public void setParent(Foo parent) { this.parent = parent; }
public Set getChildren() { return children; }
public void setChildren(Set children) { this.children = children; }
}
И его маппинг:
<class name="Foo" table="TBL_FOO">
<id name="id"><generator class="native"/></id>
<many-to-one name="parent" column="parent_id" class="Foo"/>
<set name="children" inverse="true" cascade="delete">
<key column="parent_id"/>
<one-to-many class="Foo"/>
</set>
</class>
Теперь, когда делаем
Foo foo = new Foo();
session.save(foo);
if (null == foo.getChildren())
out.println("Ба-бах!");
то получаем "Ба-бах". Это так и должно быть? Ведь, если получать Foo через запрос, то даже если у него нет детей, foo.getChildren() отдаст коллекцию с size()==0, но не null.
или
// parent - персистентный объект класса Foo, поднятый по session.query(....).
int size = parent.getChild().size();
Foo foo = new Foo();
foo.setParent(parent);
session.save(foo);
if (size == parent.getChild().size())
out.println("Ба-бах!");
ба-бах, размер коллекции детей у parent-а не изменился. Это так тоже должно быть?
А ещё вот так:
// foo - персистентный, получен по запросу.
Foo parent = foo.getParent();
if (!session.contains(parent)) {
out.println("Ба-бах!");
session.update(parent);
}
Тут парент получается не персистентный и его приходится апдейтить. Это нормально?
НГ>[/java]то получаем "Ба-бах". Это так и должно быть? Ведь, если получать Foo через запрос, то даже если у него нет детей, foo.getChildren() отдаст коллекцию с size()==0, но не null.
да, так и должно быть. вызов session.save() не изменяет сохраняемый объект (разве что асайнит id), и коллекции остаются в том же состоянии, что после конструктора.
НГ>[/java]ба-бах, размер коллекции детей у parent-а не изменился. Это так тоже должно быть?
да, так и должно быть. вызов session.save() не добавляет в коллекции объект везде где только можно. Ты сам должен распихать его по коллекциям.
НГ>[/java]Тут парент получается не персистентный и его приходится апдейтить. Это нормально?
если этот код просто продолжение примера #2, то нормально. Кстати, вызов session.save() не пишет объект в БД
Здравствуйте, Andrei N.Sobchuck, Вы писали:
Спасибо за разъяснения!
Кстати, вызов session.save() не пишет объект в БД
Ну хоть что-то знаю