-->
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.  [ 30 posts ]  Go to page Previous  1, 2
Author Message
 Post subject:
PostPosted: Fri Dec 05, 2003 9:25 am 
Beginner
Beginner

Joined: Fri Oct 24, 2003 4:28 pm
Posts: 20
gavin wrote:
Yes, Hibernate2 does (3) and (5).

The other stuff could probably be implemented by overriding EntityPersister.getCurrentState() in 2.1.


Cool. Thanks for the pointers. I'm going to give this a try next week.

Based on your suggestion, I'm looking at overriding EntityPersister.getCurrentPersistentState(). Unfortunately, this does not seem to pass in the object itself. As a work around, I'm going to create an empty object array to return and then in EntityPersister.findModified(), I will actually fill it in from the object before calling super.findModified().

If you know of a way to get a hold of the obejct in getCurrentPersistentState, let me know. Otherwise, I'll add a feature request for that :).

Thanks again.

Regards,
John


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 05, 2003 9:35 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Quote:
If you know of a way to get a hold of the obejct in getCurrentPersistentState, let me know.

you have the id, the class and the session, you should be able to look it up ;)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 05, 2003 9:50 am 
Beginner
Beginner

Joined: Fri Oct 24, 2003 4:28 pm
Posts: 20
If you know of a way to get a hold of the obejct in getCurrentPersistentState, let me know.
Quote:
you have the id, the class and the session, you should be able to look it up ;)


Ahhh...I can do this:

Code:
public Object[] getCurrentPersistentState(Serializable id, Object version, SessionImplementor session) throws HibernateException {
   Object entity = session.getEntity(new Key(id, this));
   Object[] currentState = new Object[ types.length ];
   // fill in current state from entity
   return currentState;
}


Thanks again.

Regards,
John


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 06, 2003 7:25 am 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
1) Client connects.

2 ) Client sends request to server (commands or query string), server loads objects with version numbers, sends response and forgets loaded state.

3 ) Client disconnects.

4) Client modifies graph and produces commands (or log) with version numbers.

5) Client connects and sends log (commands or query string) to server.

6) Server responde are conflicts or commands to update state on client if requested, loads new objects if requested.

7) goto 3.

It is possible to check version numbers without reloading object:

UPDATE TBL SET value=?, ...., version = version + 1 WHERE ID=? AND version=?
or
DELETE FROM TBL WHERE ID=? AND version=?

On conflict update count is 0.

As I understand hibernate is used to implement this kind of replication, is not it ?


Top
 Profile  
 
 Post subject: It works!
PostPosted: Tue Dec 09, 2003 7:30 pm 
Beginner
Beginner

Joined: Fri Oct 24, 2003 4:28 pm
Posts: 20
With a little code in a custom entity persister, I can use the original state from the object instead of reloading from the database. Here's the code:

Code:
public interface CurrentState {
   Map getCurrentState();
}

public class CustomPersister extends EntityPersister {

   public CustomPersister(PersistentClass model, SessionFactoryImplementor factory) throws HibernateException {
      super(model, factory);
   }

   public Object[] getCurrentPersistentState(Serializable id, Object version, SessionImplementor session) throws HibernateException {
      CurrentState entity = (CurrentState) session.getEntity(new Key(id, this));
      Map originalValues = entity.getCurrentState();
      Type[] types = getPropertyTypes();
      String[] propertyNames = getPropertyNames();
      Object[] values = new Object[propertyNames.length];
      boolean[] includeProperty = getPropertyUpdateability();
      for (int i = 0; i < propertyNames.length; i++) {
      if (includeProperty[i]) {
         if (originalValues.containsKey(propertyNames[i])) {
            values[i] = types[i].disassemble(originalValues.get(propertyNames[i]), session);
         } else {
            values[i] = types[i].disassemble(getPropertyValue(entity, propertyNames[i]), session);
         }
      }
   }
   return values;
}


If you see anything funky, let me know.

Thanks for making Hibernate so flexible.

Regards,
John


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 09, 2003 7:56 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
You wanna add this discussion to the Wiki? Its an interesting one....


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 11, 2003 7:22 pm 
Beginner
Beginner

Joined: Fri Oct 24, 2003 4:28 pm
Posts: 20
gavin wrote:
You wanna add this discussion to the Wiki? Its an interesting one....


Done. http://hibernate.org/161.html


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 11, 2003 7:24 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Thanks :)


Top
 Profile  
 
 Post subject: On a similar topic
PostPosted: Thu Dec 11, 2003 9:39 pm 
Beginner
Beginner

Joined: Fri Oct 24, 2003 4:28 pm
Posts: 20
So now that I can keep the original state in the object and return that to Hibernate, I want to be able to use that original state in the where clause so I don't need to add version fields to my existing tables. (If you haven't noticed, I've been heavily influenced by PowerBuilder's DataWindow).

I set optimistic-lock="dirty", but I seem to have hit a road block in SessionImpl.flushEntity() where there is the comment //note that we intentionally did _not_ pass in currentPersistentState! when the ScheduledUpdate is created. Any suggestions on how I could work around that?

Thanks,
John


Top
 Profile  
 
 Post subject: Re: On a similar topic
PostPosted: Thu Dec 11, 2003 9:53 pm 
Beginner
Beginner

Joined: Fri Oct 24, 2003 4:28 pm
Posts: 20
johnu wrote:
Any suggestions on how I could work around that?


Here's one crazy idea. In my custom EntityPersister, I added:

Code:
   public void update(Serializable id, Object[] fields, int[] dirtyFields, Object[] oldFields, Object oldVersion, Object object, SessionImplementor session) throws HibernateException {
      AbstractDomainObject entity = (AbstractDomainObject) session.getEntity(new Key(id, this));
      Map originalValues = entity.getOriginalState();
      Type[] types = getPropertyTypes();
      String[] propertyNames = getPropertyNames();
      Object[] values = new Object[propertyNames.length];
      boolean[] includeProperty = getPropertyUpdateability();
      for (int i = 0; i < propertyNames.length; i++) {
         if (includeProperty[i]) {
            if (originalValues.containsKey(propertyNames[i])) {
               values[i] = originalValues.get(propertyNames[i]);
            } else {
               values[i] = getPropertyValue(entity, propertyNames[i]);
            }
         }
      }
      super.update(id, fields, dirtyFields, values, oldVersion, object, session);
   }


See any problems with that?

Regards,
John


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 11, 2003 9:59 pm 
Newbie

Joined: Fri Dec 05, 2003 12:44 am
Posts: 16
Is there any reason why the getCurrentPersistentState method does not check the second level cache before going to the database? It seems to me that would be a good "middle ground" between the current implementation and johnu's suggestion. It's not going to be good enough if you always need to know exactly what's changed but it should cut down on the number of select-before and superfluous updates.

Oliver


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 12, 2003 4:10 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Quote:
I set optimistic-lock="dirty", but I seem to have hit a road block in SessionImpl.flushEntity()


As per the Hibernate manual, optimistic-lock="dirty" is not intended for use with detached objects (mainly because I only added this feature to support existing features of JBoss CMP).

However, my todo list mentions: "optimistic locking which uses select-before-update (for "all", "dirty")"

I think the reason that is not working so far is that (as mentioned in the JavaDoc), getCurrentPersistentState() does not, and should not, return "resolved" state. It returns the "hydrated" state only: ie. associations are represented as just id values, whereas the ScheduledUpdate expects the fully resolved objects.

I'm not sure what a fix for this problem looks like.... I'm not certain, but it might be dangerous to resolve the hydrated state in the middle of flush (new objects will get loaded), and it could certainly be a performance problem.


Quote:
Is there any reason why the getCurrentPersistentState method does not check the second level cache before going to the database?


Same reason, the cached state is hydrated, which is not the format that getCurrentPersistentState() needs to return.

I agree it makes sense to use the cache. If you want to address this limitation, you will probably just need to add an unresolve() method to the Type hierarchy.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 12, 2003 9:13 am 
Beginner
Beginner

Joined: Fri Oct 24, 2003 4:28 pm
Posts: 20
Quote:
I'm not sure what a fix for this problem looks like.... I'm not certain, but it might be dangerous to resolve the hydrated state in the middle of flush (new objects will get loaded), and it could certainly be a performance problem.


Is there an issue though if I pull the loaded state out of each object? (See my overide of EntityPersister.update()) I think what I've done is to logically move the loaded state cache out of the Session and into the object itself. I would expect there should not be a difference between passing the loaded state of the object that was pulled out of the session cache vs pulling the loaded state out of the object itself.

That's my theory anyway.

Regards,
John


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 12, 2003 9:29 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
I suspect that you probably need to implement Type.unresolve() anyway, to make the whole thing work correct.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 11, 2006 12:13 am 
Newbie

Joined: Wed Oct 11, 2006 12:06 am
Posts: 1
Hi,

This issue is fixed in version 3 or higher production versions?

We are planing to move to hibernate from a home grown DAO layer.

Thanks,
Muruges


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 30 posts ]  Go to page Previous  1, 2

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.