views:

47

answers:

2

Describe please a typical lifecycle of a Hibernate object (that maps to a db table) in a web app. Suppose, you create a new instance of an object and persist in the db. But during the app lifetime you'll be working on a detached object and finally you need to update it in the database, for example on exit. How does it look like with hibernate and spring?

p.s. Can transactions and sessions live between servlet transitions? So that we opened 1 session and use it in all servlets without a need to reopen it?

I'll try to give a descriptive example. Suppose, when the app starts, the log record is created. this can be done at once, Log log = new Log(...) and then something like save(log) -- log corresponds to a table LOG.

then, as the application processes user inputs and keeps going, new data is being accumulated.

and after the second step we could add something to a log object, a collection for example:

// now we have a tracking of what user chosen: Set thisUserChoice, // so we can update the persistent object, we have new data now ! // log.userChoices = thisUserChoice.

Here occurs the nature of my question. How are we supposed to deal with it, if we want to update the database whenever new data is gotten from a user?

In a relational model we can work with a row id, so we could get this record and update some other data of the row.

In Hibernate we are also able to load a object by its id.

But is IT THE WAY TO GO? IS ANYTHING BETTER?

+1  A: 

http://scbcd.blogspot.com/2007/01/hibernate-persistence-lifecycle.html This explains transient, persistent objects.

Also have a look at the Lifecycle interface to know what hibernate does (and it provides hooks at all stages for user to do something)

Calm Storm
Interesting, but the first article does not explain in examples how to get the detached object back to a persistent state, it only describes it in words.
EugeneP
+1  A: 

You could do everything in a single session. But that's like doing everything in a single class. It could make sense from a beginner's point of view, but nobody does it like that in practice.

In a web app, you can normally expect to have several threads running at once, each dealing with a different user. Each thread would typically have a separate session, and the session would only have managed instances of the objects that were actually needed by that user. It's not that you can completely ignore concurrency in your own code, but it's useful to have hibernate's help. If you were to do everything with one session, you would have to do all the concurrency management yourself.

Hibernate can also manage the concurrency if you have multiple application servers talking to a single database. The separate JVMs can't possibly share the same session in this case...

The lifecycle is described in the hibernate documentation (which I'm sure you've seen).

Whenever a request comes from the web client to the server, the first thing you should do is load the relevant objects (see section 10.3) so that you have persistent, not detached entities to deal with. Then, you do whatever operations are required. When the session closes (ie. when the server returns the response to the client), it will write any updates to the database. Or, if your operation involves creating new entities, you'll have to create transient ones (with new) and then call persist() or save() (see section 10.2). That will result in a managed entity -- you can make more changes to it, and hibernate will record those changes when the session closes.

I try to avoid using detached objects. But if I have to (perhaps they're stored in the user's session), then whenever they might need to be saved to the database, you'll have to use update() (see section 10.6). This converts it into a managed object, and so the session will save any changes to the database when it's closed.

Spring makes it very easy to generate a new session for each request. You would normally tell Spring to create a sessionFactory, and then every request will be given its own session. Search for "spring hibernate tutorial" and you'll find several examples.

John
@John Well, if you persist a new object, it is saved in the database, so concurrency does not make sense as only one row with this id can exist. Two threads cannot persist the same instance to a db, even if they run in different sessions. And every next thread will open a new session. Correct me if anything wrong here.
EugeneP
You are correct. Normally, you let hibernate assign the id. Two threads can both persist new objects, and hibernate will make sure that they get different ids. In section 10.2, "persist() makes a transient instance persistent. However, it does not guarantee that the identifier value will be assigned to the persistent instance immediately, the assignment might happen at flush time. persist() also guarantees that it will not execute an INSERT statement if it is called outside of transaction boundaries. This is useful in long-running conversations with an extended Session/persistence context. "
John