Issue Details (XML | Word | Printable)

Key: CORE-2796
Type: Bug Bug
Status: Closed Closed
Resolution: Won't Fix
Priority: Major Major
Assignee: Unassigned
Reporter: Craig Russell
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
JPOX Core (ARCHIVED)

Persistent interface object ids have wrong target class

Created: 02/May/06 06:40 PM   Updated: 26/May/10 07:33 PM   Resolved: 26/Jul/09 10:37 AM
Component/s: None
Affects Version/s: 1.1.0-rc-1
Fix Version/s: None


 Description  « Hide
Object ids created when persisting instances of JPOX-generated classes implementing persistent interfaces use the JPOX class as the target class.

The spec says that the target class should be the persistent interface.


Sort Order: Ascending order - Click to sort in descending order
Erik Bengtson added a comment - 02/May/06 07:02 PM
Based on the above, how do you distinguish the below?

//SingleFieldIdentity
Interface Animal
{
}

Class dog implements Animal
{
String name="snoop"; // primary-key
}

Class cat implements Animal
{
String name="snoop"; // primary-key
}



Craig Russell added a comment - 02/May/06 11:55 PM
This issue is with regard to

Animal snoop = pm.newInstance(Animal.class);
pm.makePersistent(snoop);
SingleFieldIdentity oid = (SingleFieldIdentity) pm.getObjectId(snoop);

In this case, the oid refers to a single instance in the datastore, and the mapping is specified in the metadata for the Animal interface.

Erik Bengtson added a comment - 03/May/06 09:58 AM
if...

Animal snoopy = pm.newInstance(Animal.class);
pm.makePersistent(snoopy);
SingleFieldIdentity oid = (SingleFieldIdentity) pm.getObjectId(snoopy); //snoopy@Animal.class
...
Dog snoopy= new Dog();
pm.makePersistent(snoopy);
Object snoopyId = Object pm.getObjectId(snoopy); //snoopy@Dog.class
...
Cat rex= new Cat();
pm.makePersistent(rex);
object rexId = Object pm.getObjectId(rex); //rex@Cat.class
...
Dog rex= new Dog();
pm.makePersistent(rex);
object rexId = Object pm.getObjectId(rex); //rex@Dog.class
...
Query q = pm.newQuery(Animal.class);
results = q.execute();

To correspond to the above ids, the result in the below
[snoopy@Animal.class,snoopy@Dog.class,rex@Cat.class,,rex@Dog.class]

I don't agree.

The make persistent operation should not care if the class definition of the persisting instance was generated by the JDO implementation or by another framework, or if it is an instance of an interface. We are storing instance of interfaces that can be PersistenceCapable, have other interfaces, and be manipulated by other parties between the instantiation and persistence, when the instance is retrieved back from database it must be of the same class.

The make persistent must store the instance in a manner that it's capable to reconstruct a new instance of that same class. During reconstruction, the only way to resolve the class is storing the class name of the instance (discriminator) or putting into different tables(one table per class name).
After a cold boot and with the class name on hands, we look after that class definition in the classloader to be able to reconstruct, and if the definition is there, we will not generate a new class definition.

So, my point here is that snoopy's id target class should have the concrete class.

Animal snoopy = pm.newInstance(Animal.class);
pm.makePersistent(snoopy);
SingleFieldIdentity oid = (SingleFieldIdentity) pm.getObjectId(snoopy); //snoopy@AnimalImpl.class
...
Dog snoopy= new Dog();
pm.makePersistent(snoopy);
Object snoopyId = Object pm.getObjectId(snoopy); //snoopy@Dog.class
...
Cat rex= new Cat();
pm.makePersistent(rex);
object rexId = Object pm.getObjectId(rex); //rex@Cat.class
...
Dog rex= new Dog();
pm.makePersistent(rex);
object rexId = Object pm.getObjectId(rex); //rex@Dog.class
...
Query q = pm.newQuery(Animal.class);
results = q.execute();

To correspond to the above ids, the result in the below
[snoopy@AnimalImpl.class,snoopy@Dog.class,rex@Cat.class,,rex@Dog.class]

Other examples could be

useInstanceGenerator("default");
Animal snoopy = pm.newInstance(Animal.class); //implements PersistenceCapable
useInstanceGenerator("spring");
Animal snoopyBrother1 = pm.newInstance(Animal.class); //implements PersistenceCapable, Beagle
useInstanceGenerator("emf");
Animal snoopyBrother2 = pm.newInstance(Animal.class); //implements PersistenceCapable, FlyingAce
pm.makePersistent(snoopy);
pm.makePersistent(snoopyBrother1);
pm.makePersistent(snoopyBrother2);
SingleFieldIdentity snoopyOid = (SingleFieldIdentity) pm.getObjectId(snoopy); //snoopy@AnimalDefaultImpl.class
SingleFieldIdentity snoopyBrother1Oid = (SingleFieldIdentity) pm.getObjectId(snoopyBrother1); //snoopyBrother1@AnimalSpringImpl.class
SingleFieldIdentity snoopyBrother2Oid = (SingleFieldIdentity) pm.getObjectId(snoopyBrother2); //snoopyBrother2@AnimalEmfImpl.class

more examples...

useInstanceGenerator("default");
Animal snoopy = pm.newInstance(Animal.class); //implements PersistenceCapable
snoopy.setName("snoopy");

useInstanceGenerator("spring");
Animal snoopyBeagle= pm.newInstance(Animal.class); //implements PersistenceCapable, Beagle
snoopyBeagle.setName("snoopy");

useInstanceGenerator("emf");
Animal snoopyAce = pm.newInstance(Animal.class); //implements PersistenceCapable, FlyingAce
snoopyAce.setName("snoopy");

Animal snoopyJoeCool = anotherFramework.create(Animal.class); //implements PersistenceCapable, JoeCool
snoopyJoeCool .setName("snoopy");

pm.makePersistent(snoopy);
pm.makePersistent(snoopyBeagle);
pm.makePersistent(snoopyAce);
pm.makePersistent(snoopyJoeCool);

SingleFieldIdentity snoopyOid = (SingleFieldIdentity) pm.getObjectId(snoopy); //snoopy@AnimalDefaultImpl.class
SingleFieldIdentity snoopyBeagleOid = (SingleFieldIdentity) pm.getObjectId(snoopyBeagle); //snoopy@AnimalSpringImpl.class
SingleFieldIdentity snoopyAceOid = (SingleFieldIdentity) pm.getObjectId(snoopyAce); //snoopy@AnimalEmfImpl.class
SingleFieldIdentity snoopyJoeCoolOid = (SingleFieldIdentity) pm.getObjectId(snoopyJoeCool); //snoopy@AnimalAnotherImpl.class

retrieving from database...
[snoopy@AnimalDefaultImpl.class,snoopy@AnimalSpringImpl.class,snoopy@AnimalEmfImpl.class,snoopy@AnimalAnotherImpl.class]

Andy Jefferson added a comment - 26/Jul/09 10:37 AM
Marking as Wont Fix since there was no consensus in the issue description, and JPOX/DataNucleus pass the JDO TCK as it is