Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Hibernate saveOrUpdate and the Persistence Life Cycle

Tags:

java

hibernate

Let's look at a simple example of a dog and a cat that are friends. This isn't a rare occurrence. It also has the benefit of being much more interesting than my business case.

We want a function called "saveFriends" that takes a dog name and a cat name. We'll save the Dog and then the Cat. For this example to work, the cat is going to have a reference back to the dog. I understand this isn't an ideal example, but it's cute and works for our purposes.

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 (extends 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);
}

Now, assume for a minute that I would like to use either example A or example B to save my friend. Is one better than the other to use?

Furthermore, won't example B get you the infamous "not-null property references a null or transient value" error? I'm only guessing here but I would think this is because the Dog is still in the session.

I'll understand if neither of those examples work, but please explain why.

like image 540
Stephano Avatar asked Jan 21 '23 21:01

Stephano


1 Answers

Now, assume for a minute that I would like to use either example A or example B to save my friend. Is one better than the other to use?

Both examples will work (in example B, Hibernate will flush the session before query executions so it will insert the dog before the select) but I don't see the point of doing an extra select (example B) when you already have the dog instance. I would just go for example A.

Furthermore, won't example B get you the infamous "not-null property references a null or transient value" error?

No (see above). In example B, the dog is not transient anymore. In example A, inserts will be done in the right order.

I'm only guessing here but I would think this is because the Dog is still in the session.

The first level cache (the session) is used for find by id, which is not the case here.

like image 95
Pascal Thivent Avatar answered Jan 26 '23 09:01

Pascal Thivent