I know that object is in detached state when we already hit save and we have to re-attach it.
Suppose i have one form with html text fields and there is save button which saves the text in database.
i have thise code
public void edit(Person person) {
logger.debug("Editing existing person");
// Retrieve session from Hibernate
Session session = sessionFactory.getCurrentSession();
// Retrieve existing person via id
Person existingPerson = (Person) session.get(Person.class, person.getId());
// Assign updated values to this person
existingPerson.setFirstName(person.getFirstName开发者_JS百科());
existingPerson.setLastName(existingPerson.getLastName());
existingPerson.setMoney(existingPerson.getMoney());
// Save updates
session.save(existingPerson);
}
Now i can hit save any number of time to save the data.
Now does that mean that once i hit save first time , it becomes detached. So do i need to do something special for that or it does not matter.
I want to know under what condition i need to program anything about detached state
As soon as the session used to save, load, get or find an entity has been closed, the entity becomes detached. This means that it's not connected anymore to a session, and works like any other POJO.
When an entity is attached and you change one of its properties, Hibernate automatically saves the changes you made to the corresponding row in the database (at flush/commit time).
When it's detached, the changes you made to the object are not saved automatically to the database. In order to save the changes, you need to do it yourself, by calling the session.update() or session.merge(). Both methods do more or less the same thing, but do it differently. I personnally prefer using merge, which is less dangerous and leads to less bugs.
Read http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-detached for more details
In your code, the person passed as argument to the edit method is probably detached. What you're doing is getting the person with the same ID as the one passed from the session. existingPerson
is thus attached. Then you copy all the properties from the detached person to the attached existingPerson. And finally, you save the existingPerson.
There are 3 problems with this code :
- save doesn't do what you think it does. save is for inserting a new person object. Your existing person already exists and already has an ID, so the operation to use is update or merge.
- You don't even need to use update or merge, because since existingPerson is attached to the session, the changes you make (setFirstName, setLastName, etc.) will automatically be made persistent by Hibernate at flush time. It's transparent.
- The algorithm you have implemented is the same one (except for cascades, etc.) as the one used by merge, which does all this automatically for you.
It should thus be changed to :
public void edit(Person person) {
logger.debug("Editing existing person, which is a detached object");
// Retrieve session from Hibernate
Session session = sessionFactory.getCurrentSession();
// Retrieve existing person via id, then copy everything from detached person
// to attached one, and return attached one
Person existingPerson = (Person) session.merge(person);
}
精彩评论