-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Proble with lazy loading, cache, LockMode.NONE and DB
PostPosted: Fri Dec 17, 2004 3:14 pm 
Newbie

Joined: Fri Dec 17, 2004 2:38 pm
Posts: 11
Location: Buenos Aires
Hello,

I've a very strange problem here. We're working with hibernate and hivemind.

In the past we work in ours CRUD’S with this steps:

a- Find an Object with our Finder Component. All the objects we use are retrieved with this component. This component after obtain the object, closes the session.
b- Update the disconnected object as the user wish
c- The user accepts or deny the changes
d- If he accepts, we invoke our CRUD component, which opens another session, attaches the object to this session, flushes it and closes the session. And that's all. We update the DB.
d- If the user doesn't accept, the object is discarded and as it is a disconnected object, none is updated. The garbage collector makes the dirty work and the object is killed.

The consequence: It works but as we close the session, we couldn't use lazy-initialisation in our domain object. We need to make something about that.

As we can't store the Session in the HTTPContext, but we need to use lazy loading, we make a proxy factory in our Finder component. This proxy factory make a proxy which intercepts all the methods in the domain object. the interceptor works with this steps.

a- The proxy verifies that the session is open
b- If not, the proxy opens a new Session and make a session.update(target). But the session is Locked with LockMode.NONE, then, in theory, nothing is sent to the DB if we won't explicitly send a flush to the session.
c- The proxy delegate the flow to the object method.

At the end, when the thread is discarded, the session is closed. The finder Component doesn’t close session any more. As the session is LockMode.NONE, it doesn't make a flush, then the DB isn't be updated. And then, we have lazy!. But there it comes our problem.

After that, we attached the JbossTreeCache and make cache transactional all the objects. When we deny the changes in the step "c" in the first step list, we noticed that even when the DB isn't updated, Hibernate updates the 2nd level cache, producing a inconsistency between the 2nd level cache and the DB. We associate this behaviour with the reconnection in the proxy cache, because if we didn't surround our object with our proxy everything works fine (But without lazy)

We can't understand why the 2nd level cache is updated when the flush command isn't executed. Is it a normal behaviour?


Hibernate version:2.1.7

Mapping documents:NYA

Code between sessionFactory.openSession() and session.close():N/A

Full stack trace of any exception that occurs:N/A

Name and version of the database you are using:N/A

The generated SQL (show_sql=true):N/A

Debug level Hibernate log excerpt:N/A


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 17, 2004 3:20 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
Quote:
As we can't store the Session in the HTTPContext

why can't you store it? this is the long session per application transaction pattern, much simplier than your system.

Quote:
b- If not, the proxy opens a new Session and make a session.update(target). But the session is Locked with LockMode.NONE, then, in theory, nothing is sent to the DB if we won't explicitly send a flush to the session.

partially wrong, if you let flushMode.AUTO, you don't know when the session is going to be flushed, it can be executing a query or calling commit(). If you really want this behaviour, set flushMode.NEVER.

About JBossTreeCache, i don't know.

But it seems to me you'd better switch to long session per application transaction pattern if you don't have much rework.

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 17, 2004 4:23 pm 
Newbie

Joined: Fri Dec 17, 2004 2:38 pm
Posts: 11
Location: Buenos Aires
Quote:
anthony wrote:
Quote:
As we can't store the Session in the HTTPContext

why can't you store it? this is the long session per application transaction pattern, much simplier than your system.


It's an architectural desition. I can't do much about this. :(


Quote:
Quote:
b- If not, the proxy opens a new Session and make a session.update(target). But the session is Locked with LockMode.NONE, then, in theory, nothing is sent to the DB if we won't explicitly send a flush to the session.

partially wrong, if you let flushMode.AUTO, you don't know when the session is going to be flushed, it can be executing a query or calling commit(). If you really want this behaviour, set flushMode.NEVER.


Excuse me, I'm wrong. I use flushMode.NEVER as you said.

Quote:
About JBossTreeCache, i don't know.

But it seems to me you'd better switch to long session per application transaction pattern if you don't have much rework.
[/quote]

it's like a session per transaction, because once the session is open, we use the same session in the entire request (Since it's open for the first time to it is closed in the ThreadDiscard in the end of the request).

But I think if I throw the proxy and I make a long transaction in the "Hibernate in action" way with the HTTPFilter and the HTTPSession, the problem will remain. Because if I put FlushMode.NEVER and I don't flush the session, I think the 2nd level cache won't be modified.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 17, 2004 4:54 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
ok now are you re attaching the object using session.update or session.lock?

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 17, 2004 4:59 pm 
Newbie

Joined: Fri Dec 17, 2004 2:38 pm
Posts: 11
Location: Buenos Aires
anthony wrote:
ok now are you re attaching the object using session.update or session.lock?


session.update(...)

protected void checkConnected() {
if (session == null || !session.isOpen()) {
reconnect();
}
}

protected void reconnect() {
this.session = sessionService.getSession(target.getClass(),SessionOptions.MANAGED);
try {
this.session.update(target);
} catch (HibernateException e) {
throw new BasicRuntimeException("CANT_RECONNECT_ENTITY", e,
new Object[] { this, target });
}
}

the interceptor

builder.addln("checkConnected();");

boolean notVoid = !methodSignature.getReturnType().equals(
void.class);
builder.addln((notVoid ? "return ($r)" : "($r)") + " (("
+ entityClass.getName() + ") target).{0}($$);",
methodSignature.getName());


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 17, 2004 5:25 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
try session.lock

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.