Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Seeding the 'version' column starting number?(Does anyone know how to pre-seed the starting value of the version column used for optimistic lock detection?)
Seeding the 'version' column starting number? [message #1590090] Wed, 28 January 2015 20:57 Go to next message
Thom Park is currently offline Thom ParkFriend
Messages: 12
Registered: June 2012
Junior Member
I have a business case for wanting to start the version counter at a specific value for a given object.

Currently, I'm having to new up an object, persist it, then ,under the covers (via SQL) manually change the version number held in the version column, then refresh the cached entry with the updated row.

My problem with this is that it's not an atomic operation (persist, sql update, refresh) are all separate operations so mischief could occur is another thread read the object prior to my updates being done.

It would be ideal if I could pre-set the version number for a new object at object creation time.

Do any of the eclipselink intelligensia know of a way of doing this?

-Thom
Re: Seeding the 'version' column starting number? [message #1599422 is a reply to message #1590090] Tue, 03 February 2015 16:23 Go to previous messageGo to next message
Will Dazey is currently offline Will DazeyFriend
Messages: 10
Registered: February 2015
Junior Member
After looking over the 2.1 spec, it seems the behavior of setting the version field is controlled by the provider and should not extend to the client.
3.4.2 Version Attributes
The Version field or property is used by the persistence provider to perform optimistic locking. It is
accessed and/or set by the persistence provider in the course of performing lifecycle operations on the
entity instance. An entity is automatically enabled for optimistic locking if it has a property or field
mapped with a Version mapping.
An entity may access the state of its version field or property or export a method for use by the application
to access the version, but must not modify the version value. With the exception noted in section
4.10, only the persistence provider is permitted to set or update the value of the version attribute in
the object.

The exception in 4.10 that it refers to covers batch updates and deletions. Any changes done this way will not be supported by the optimistic locking checker, must be manually verified, and will put the persistence context out of sync.

Are you updating version values on an entity instance or entity class basis for your business case? Using a SessionCustomizer, perhaps you can add an EventListener. Then you can intercept an event like PostExecuteQuery and execute an update query. Otherwise, all I can suggest is making both your persist call and your update query part of the same transaction and turn off the shared-cache in your persistence unit
<shared-cache-mode>NONE</shared-cache-mode>

Open an enhancement for this. It may get more attention that way.
Re: Seeding the 'version' column starting number? [message #1603076 is a reply to message #1599422] Fri, 06 February 2015 00:50 Go to previous messageGo to next message
Thom Park is currently offline Thom ParkFriend
Messages: 12
Registered: June 2012
Junior Member
Thanks for your reply - I appreciate it.
I'll do as you suggest and propose an enhancement.

I fully understand that the "version" fields should be treated as "hands off - this is owned by the provider implementation', but I had hoped to at least initialize to a specific value on object creation.

I've tried numerous 'workarounds', none of which behave atomically.

Thanks again,

Thom
Re: Seeding the 'version' column starting number? [message #1604318 is a reply to message #1603076] Fri, 06 February 2015 19:55 Go to previous messageGo to next message
Will Dazey is currently offline Will DazeyFriend
Messages: 10
Registered: February 2015
Junior Member
Ya, I attempted a patch for this, but it ended up exposing too much. The default value is dictated by this hardset method in the VersionLockingPolicy.
protected Object getInitialWriteValue(AbstractSession session) {
        return Long.valueOf(1);
    }

Of course modifying this would only set it on the ClassDescription level, not the individual Entity instance level that I think you are trying to achieve. For that, itll get even trickier/uglier Confused
Re: Seeding the 'version' column starting number? [message #1633162 is a reply to message #1604318] Tue, 24 February 2015 18:16 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1389
Registered: July 2009
Senior Member
You might want to look into using a customizer to set your own optimistic locking policy that extends the VersionLockingPolicy class and overrides the setupWriteFieldsForInsert method. Instead of calling getInitialWriteValue, it can use query.getObject() to access the entity to be inserted to figure out the value you want to use. The current implementation looks like:

public void setupWriteFieldsForInsert(ObjectLevelModifyQuery query) {
Object lockValue = getInitialWriteValue(query.getSession());
ObjectChangeSet objectChangeSet = query.getObjectChangeSet();
if (objectChangeSet != null) {
objectChangeSet.setInitialWriteLockValue(lockValue);
}
updateWriteLockValueForWrite(query, lockValue);
}

writeQuery.getObject()
Re: Seeding the 'version' column starting number? [message #1635510 is a reply to message #1633162] Wed, 25 February 2015 20:54 Go to previous messageGo to next message
Gordon Yorke is currently offline Gordon YorkeFriend
Messages: 78
Registered: July 2009
Member
You could create a separate PersistenceUnit just for data insert where you have disabled optimistic locking either through a Session Customizer and a named Session (https://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_session_name.htm ) or by changing the @Version to @Basic in the entities.

I also recommend filing a bug/enhancement request for this feature.
Re: Seeding the 'version' column starting number? [message #1635542 is a reply to message #1633162] Wed, 25 February 2015 21:11 Go to previous messageGo to next message
Will Dazey is currently offline Will DazeyFriend
Messages: 10
Registered: February 2015
Junior Member
The explanation in EclipseLink doc for how to configure optimistic locking policies seems to indicate configuration can be done on existing instances of locking policies, but I couldn't find any examples for extending with custom policies. I worked up a small example of how to make it work, but it wasn't completely obvious at first that initialization values are required when creating the custom policy instance.

This is a simple example that can add implementation to setupWriteFieldsForInsert() or getInitialWriteValue(), depending on the rules for your business case, being object or class, respectively:
public class GenericSessionCustomizer implements SessionCustomizer {

    public class GenericVersionLockingPolicy extends VersionLockingPolicy {
       
        public GenericVersionLockingPolicy(DatabaseField field){
            super(field);
            storeInObject();
        }
        //Override methods
    }
    
    @Override
    public void customize(Session session) throws Exception {
        for (ClassDescriptor descriptor : session.getDescriptors().values()) {
            OptimisticLockingPolicy orig = descriptor.getOptimisticLockingPolicy();
            descriptor.setOptimisticLockingPolicy(new GenericVersionLockingPolicy(orig.getWriteLockField()));
        }
    }
}


Alternatively, you could implement in DescriptorCustomizer classes for specific entity classes that need this business case.
public class GenericDescriptorCustomizer implements DescriptorCustomizer {

    public class GenericVersionLockingPolicy extends VersionLockingPolicy {

        public GenericVersionLockingPolicy(DatabaseField field) {
            super(field);
            storeInObject();
        }
        //Override methods
    }

    @Override
    public void customize(ClassDescriptor descriptor) throws Exception {
        OptimisticLockingPolicy op = descriptor.getOptimisticLockingPolicy();
        descriptor.setOptimisticLockingPolicy(new GenericVersionLockingPolicy(op.getWriteLockField()));
    }
}
Re: Seeding the 'version' column starting number? [message #1652138 is a reply to message #1635542] Thu, 05 March 2015 18:23 Go to previous message
Thom Park is currently offline Thom ParkFriend
Messages: 12
Registered: June 2012
Junior Member
Thanks, everyone, for your stellar responses.
I'll work through these suggestions and see if one of them will work in my specific case where I want, on create, to specify a starting version #.

Thanks again,

Thom
Previous Topic:Foriegn Key Not Updating
Next Topic:org.eclipse.persistence.mappings.converters.Converter code is failing for oracle12C but working 11g
Goto Forum:
  


Current Time: Tue Oct 08 12:27:24 GMT 2024

Powered by FUDForum. Page generated in 0.26503 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top