Details
Description
A code snippet similar to the following should recreate the problem:
Database database = jdo.getDatabase();
database.begin();
Foo foo = null;
try {
foo = (Foo) database.load(Foo.class, new Integer(1));
} catch (ObjectNotFoundException e) {
foo = new Foo();
database.create(foo);
}
database.commit();
database.close();
When using a key-generator="IDENTITY" mapping the create() following the
unsuccessful load() will cause the following exception when '1' happens to be
the next identity key to be generated:
org.exolab.castor.jdo.PersistenceException: Nested error: Key Generator
Failure. Duplicated Identity is generated!
at org.exolab.castor.persist.LockEngine.create(Unknown Source)
at org.exolab.castor.persist.TransactionContext.create(Unknown Source)
at org.exolab.castor.jdo.engine.DatabaseImpl.create(Unknown Source)
At the same time, the following exception is printed to the console:
org.exolab.castor.jdo.LockNotGrantedException: Lock is already existed for the
new oid.
at org.exolab.castor.persist.LockEngine$TypeInfo.rename(Unknown Source)
at org.exolab.castor.persist.LockEngine$TypeInfo.access$400(Unknown
Source)
at org.exolab.castor.persist.LockEngine.create(Unknown Source)
at org.exolab.castor.persist.TransactionContext.create(Unknown Source)
at org.exolab.castor.jdo.engine.DatabaseImpl.create(Unknown Source)
I reproduced the problem with a simple class and the MAX generator.
The sequence is
no longer active, but still in the locks Map
generation) must be converted to the new one, which happen to be
equals to the one generated by the load call
=> crash in TypeInfo.rename
I first tried to remove the lock when catching the first exception,
but some test cases are broken by this.
The next thing to try is to use a more precise test in TypeInfo.rename, I
tried :
if ( newentry != null && !newentry.isDisposable())
throw new LockNotGrantedException("Lock is already existed for the new oid.");
All tests are OK with this one but I'm not yet sure of the validity of this
patch... Some more work on this is needed.