Понимание Hibernate saveOrUpdate и жизненного цикла постоянства - PullRequest
3 голосов
/ 15 июня 2010

Давайте рассмотрим простой пример собаки и кошки, которые являются друзьями.Это не редкое явление.Он также имеет преимущество в том, что он гораздо интереснее моего бизнес-кейса.

Нам нужна функция с именем saveFriends, которая принимает имя собаки и имя кошки.Мы спасем Пса, а затем Кота.Чтобы этот пример работал, у кота будет ссылка на собаку.Я понимаю, что это не идеальный пример, но это мило и работает для наших целей.

FriendService.java

public int saveFriends(String dogName, String catName) {
    Dog fido = new Dog();
    Cat felix = new Cat();

    fido.name = dogName;
    fido = animalDao.saveDog(fido);

    felix.name = catName;
    [ex.A]felix.friend = fido;
    [ex.B]felix.friend = animalDao.getDogByName(dogName);
    animalDao.saveCat(felix);
}

AnimalDao.java (расширяет HibernateDaoSupport)

public Dog saveDog(Dog dog) {
    getHibernateTemplate().saveOrUpdate(dog);
    return dog
}

public Cat saveCat(Cat cat) {
    getHibernateTemplate().saveOrUpdate(cat);
    return cat;
}

public Dog getDogByName(String name) {
    return (Dog) getHibernateTemplate().find("from Dog where name=?", name).get(0);
}

Теперь на минуту предположим, что я хотел бы использовать либо пример A, либо пример B, чтобы спасти моего друга.Один лучше другого использовать?

Кроме того, не приведет ли пример B к печально известной ошибке "not-null свойство ссылается на нулевое или временное значение"?Я только догадываюсь здесь, но я думаю, что это потому, что Пес все еще находится на сессии.

Я пойму, если ни один из этих примеров не сработает, но, пожалуйста, объясните, почему.

Ответы [ 3 ]

4 голосов
/ 16 июня 2010

Теперь предположим на минуту, что я хотел бы использовать либо пример А, либо пример Б, чтобы спасти моего друга. Один лучше другого использовать?

Оба примера будут работать (в примере B Hibernate сбросит сессию перед выполнением запроса , поэтому он вставит собаку перед выбором), но я не вижу смысла делать дополнительный выбор ( пример Б) когда у вас уже есть экземпляр собаки. Я бы просто пошел к примеру А.

Кроме того, не приведет ли пример B к печально известной ошибке "not-null свойство ссылается на нулевое или временное значение"?

Нет (см. Выше). В примере B собака больше не является временной. В примере A вставки будут выполнены в правильном порядке.

Я только догадываюсь здесь, но я думаю, что это потому, что Пес все еще находится на сессии.

Кэш первого уровня (сеанс) используется для поиска по идентификатору, что здесь не так.

2 голосов
/ 16 июня 2010

Оба будут работать правильно, но они не одинаково эффективны. В B, поскольку он выполняет запрос, он не только накладывает накладные расходы на сам запрос, но и заставляет hibernate сбрасывать изменения в базе данных - изменения, которые могли храниться в памяти до фиксации транзакции и отправляться со многими другие изменения.

Соединения с БД, как правило, страдают довольно высокой задержкой, поэтому пакетная обработка используется для одновременной отправки множества изменений, уменьшая задержку на оператор. Разбиение набора изменений на множество небольших изменений влечет за собой относительно большую нагрузку на оператор, чем большая группа изменений. Поэтому лучше всего отправлять изменения вместе, когда это возможно.

2 голосов
/ 15 июня 2010

Из документов на hibernate

saveOrUpdate () делает следующее:

, если объект уже сохраняется в этом сеансе, ничего не делать

если другой объект, связанный с сеансом, имеет такой же идентификатор, выведите исключение

, если у объекта нет свойства идентификатора, сохраните () его

, если идентификатор объекта имеет значениеназначенный новому экземпляру объекта, save () it

, если объект версионирован с помощью или, и значение свойства version совпадает со значением, назначенным новому экземпляру объекта, save () it

иначе обновить () объект

По производительности я бы сказал, что назначение ссылки на объект, на который указывает fido, будет быстрее, поскольку вы не открываете соединение с базой данных.

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