You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jdo-dev@db.apache.org by cbeams <cb...@gmail.com> on 2007/09/14 07:53:31 UTC

Please review CopyOnAttach property proposal

All,

This is following on to conversations started about a month ago  
regarding a new pmf property, CopyOnAttach, that when set to false  
would force makePersistent to transition detached parameters back to  
P-clean or P-dirty and return the very same instance without making a  
copy.  For clarity, an example use case follows:

<example>

PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory 
("jdo.properties");

assert pmf.getDetachAllOnCommit() == true;
assert pmf.getCopyOnAttach() == false;

// assuming (for convenience) that there's a single instance of an  
Employee in the database, let's query for it, detaching on commit.
final Employee emp;
{
     PersistenceManager pm = pmf.getPersistenceManager();
     pm.currentTransaction().begin();
     emp = (Employee) pm.newQuery("select unique from  
Employee").execute();
     pm.currentTransaction().commit();
}

// 'emp' is now detached-clean
assert isDetached(emp) && isClean(emp);

emp.setAge(32);

// 'emp' is now detached-dirty
assert isDetached(emp) && isDirty(emp);

Employee returned;
{
     PersistenceManager pm = pmf.getPersistenceManager();
     pm.currentTransaction().begin();
     returned = pm.makePersistent(emp);
     pm.currentTransaction().commit();
}

// 'emp' is now detached-clean.
assert isDetached(emp) && isClean(emp);

// and no copy was made during attachment
assert emp == returned;

</example>



Normally, without CopyOnAttach == false (i.e.: current-world  
behavior), the final state of 'emp' in the example above would be  
'detached-dirty' and 'returned' would be a brand new instance ending  
up 'detached-clean'.

The new CopyOnAttach == false functionality allows the user to  
detach, modify and attach the same object an indefinite number of  
times without incurring a) the performance cost of copying and b) the  
usability cost of having to assign 'emp' to the return value on each  
call to makePersistent().

In the current world, the user *could* detach, modify and attach the  
same 'emp' object an indefinite number of times, simply disregarding  
the returned value, but there are two ill effects of doing this: a)  
copies are needlessly made, and worse, b) the parameter 'emp'  
instance remains forever 'detached-dirty'.  This means that any field  
ever dirtied in 'emp' will always be flushed to the datastore, even  
if it is not further modified during subsequent iterations.  This  
would be confusing to the user and another potential source of  
performance problems.  Allowing the 'emp' instance to transition back  
to persistent-dirty and subsequently to detached-clean after commit  
solves this problem completely.


I understand that I'm getting this in just under the wire for  
tomorrow's conference call; I don't expect folks to have reviewed it  
with such short lead time.  But it can provide some fodder for  
discussion, and we'll all have a week to consider it before the next  
call.  Please scrutinize this heavily; I consider this proposal a  
good start, and not necessarily complete by any means.

I've included the proposal inline below, and also attached it as an  
RTF document.  You'll likely find the RTF more readable as it uses  
bolding and italics to distinguish changes, etc.

I'll also be attaching this proposal to the JIRA issue for this topic  
at http://issues.apache.org/jira/browse/JDO-522.  I suggest that we  
add comments and changes there to cut down on duplications between  
email and JIRA.


<proposed>

11.1:
* CopyOnAttach: the PersistenceManager mode that indicates whether  
calls to makePersistent(pc) where pc is a detached instance will  
return the same instance or a copy of that instance.  For backward  
compatibility reasons, this flag must default to ‘true’.
A11.1-40 [PersistenceManagerFactory.setCopyOnAttach(boolean flag)  
sets the value of the CopyOnAttach flag.]
A11.1-41 [PersistenceManagerFactory.getCopyOnAttach() gets the value  
of the CopyOnAttach flag.]


11.1-33:
+ “javax.jdo.option.CopyOnAttach”

A5.5.9-2 [Detached-dirty instances do not change their life cycle  
state unless CopyOnAttach is set to false.  If CopyOnAttach is false,  
detached-dirty instances may transition to persistent-clean or  
persistent-dirty when attached via makePersistent (see 5.9 for details)]

5.9:
Add the following rows to the last table in this section with headings:
| method / current state | P-nontrans-dirty | detached-clean |  
detached-dirty |

+ | makePersistent with CopyOnAttach=false | unchanged | parameter: P- 
clean, returned: P-clean (same instance as parameter) | parameter: P- 
dirty, returned: P-dirty (same instance as parameter) |
+ | makePersistent with CopyOnAttach=false when an object with the  
same identity already exists in the L1 cache |  unchanged | error |  
error |

(this last row stipulates that usage of CopyOnAttach=false is only  
valid in cases where a new PersistenceManager is used for each call  
to makePersistent.  Said another way, multiple calls to  
makePersistent with the same pc against the same pm will result in a  
JDOUserException.  It is unknown / unspecified what implications this  
has on L2 caches... comments?)

12.6.7:
A12.5.7-7: [These methods have no effect on parameter persistent  
instances already managed by this PersistenceManager unless the  
CopyOnAttach method is set to false, in which case detached parameter  
instances will be transitioned to P-dirty or P-clean per section 5.9]
A12.6.7-1:
[...]
The return value for detached instances is the persistent instance  
corresponding to the detached instance.  In the case of CopyOnAttach  
being set to false, the return value is the same object instance as  
the detached parameter instance, where the parameter has been  
transitioned from detached to P-dirty or P-clean per the rules in  
section 5.9

The return values for makePersistentAll methods correspond by  
position to the parameter instances.  In the case of CopyOnAttach  
being set to false, the object instances in the collection returned  
by makePersistentAll must be the same object instances as found in  
the parameter collection, each having been transitioned to P-dirty or  
P-clean as appropriate per the rules in section 5.9

</proposed>


Regards,

- Chris

Chris Beams