This post is going to make a few assumptions:
1) You're using S2 and Spring
2) You're using Spring's OSIV filter (as opposed to Hibernate's)
3) You're using Spring's Hibernate DAO framework
4) You're using a Spring-configured transaction manager
5) You're declaring transaction boundaries and their configuration
somehow (declaratively in the xml, for example).
That's a lot of assumptions but that's also the typical setup (in my
experience, at least) when using S2, Spring, and Hibernate. If you're
*not* doing the above ignore the rest of the post. And ask yourself why
you're not. :-)
Assuming that's your setup, then I'm a little confused by this thread.
To get the behavior you describe you actually have to work at it a
little. And the implication is that you're getting it by accident.
Here's a snippet from the docs for Spring's OSIV filter:
"NOTE: This filter will by default not flush the Hibernate Session, with
the flush mode set to FlushMode.NEVER. It assumes to be used in
combination with service layer transactions that care for the flushing:
The active transaction manager will temporarily change the flush mode to
FlushMode.AUTO during a read-write transaction, with the flush mode
reset to FlushMode.NEVER at the end of each transaction. If you intend
to use this filter without transactions, consider changing the default
flush mode (through the "flushMode" property)."
It does this to avoid exactly the problem you're having (objects dirtied
by the view getting automatically persisted). Here's a thread about
this from somebody who wanted to be able to write from within the OSIV
session but was having trouble doing it:
http://forum.springframework.org/archive/index.php/t-12414.html
Even though it's pretty much the opposite problem you're having, I think
it will be educational to give that a read.
Now, you're saying you're getting non-default behavior (your dirty
objects are being auto-flushed.). That implies to me that your
transaction manager is changing the flush-mode of the OSIV session,
probably because you've used server/dao methods configured as read/write
instead of read-only.
If that's the case, the recommended solution here would be to see if you
can easily re-configure the transactions involved with this view. If
they're a bunch of hibernate-related calls that are all read-only, just
be sure that spring's transaction config *knows* that they're read only.
That way the OSIV filter will "do the right thing".
Or did I miss something?
- Gary
Alberto A. Flores wrote:
Thank you everyone for all your input.
I'm currently opting for changing my code (luckily is not that much) to
never maintained a "persistent" object within the ValueStack, but rather
a "transient" object. Of course, this is an additional overhead (have to
copy the object, query, etc, etc), but I think is our best approach
since Hibernate Validator is not viable option right now (I would also
argue that validation could/should be pushed back to the model,
unfortunately we are working with a poorly design db where we use
reverse engineering to build all hbm and src files and I'm not sure if I
have enough resources to fix that part of our build, e.g. add Hibernate
Validator, modify templates, etc).
If I may ask, how to "avoid the transaction commit when validation
fails" (as you mentioned)? Is there an interceptor to handle this
scenario? I see that the workflow interceptor is part of the xwork
package (not available with Struts2 distribution source code) and before
I jump into repackaging one from xwork source (which I'm not even sure
where can I find one), I would probably consider writing one myself to
handle this case. I also notice that the validate() method is triggered
before the prepare() method (which makes total sense), however I would
like to guess that this scenario is best handled by an "interceptor" as
I sensed such is the recommended approach in the documentation.
Ted Husted wrote:
When a workflow automatically opens and closes a transaction, so that
it can cover multiple operations, and something goes wrong during the
course of the transaction, then we need to rollback the transaction.
In the case of validation, sometimes changes are made to a property
which causes it to become (for example) NULL, and later in the
lifecycle the validator sees that the property is NULL, and raises the
validation error. But, by then, the property is changed, and the
Hibernate Session (or JPA EntityManager) will commit the change when
the transaction is automatically closed.
Since the Hibernate Validator and JSR 299 push validation back to the
model (where it arguably belongs), making it easy to signal for a
rollback in a multioperation transaction becomes more important.
I'm still ramping up on the JPA myself, but in some early tests I
found that not committing the transaction has the same affect of a
rollback.
-- HTH, Ted
* <http://www.StrutsMentor.com/>
On Dec 17, 2007 4:04 PM, Alberto A. Flores <[EMAIL PROTECTED]> wrote:
Is anyone using openSessionInView with Struts 2 (Hibernate, Spring)?
I've found a problem where a domain model is still persisted (even
though I'm not saving it) after validation finishes (showing validation
errors). My prepare method makes a query (using a
HibernateTemplate().get() method) but that's all? Has anyone seen
something similar?
I'm very sorry if this is not a Struts2 question, but thought of asking
since Struts2 is using Filters now and was wondering if anyone has seen
any similar behavior.
Thanks,
--
Alberto A. Flores
http://www.linkedin.com/in/aflores
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
------------------------------------------------------------------------
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]