|
From: <fi...@so...> - 2004-06-08 02:25:04
|
Hi this are the changes I made to org.xorm.InterfaceInvocationHandler.java
to preserve the identity outside transactions and prevents duplication of
instances
there is some other changes to make the system more compliant jdo specs
but i still have problems in modifing this code, we must separe jdo
status managing from row management and interface handling...
one way could be use the state pattern...
there are some todo ad some question(usually marked with "sj777 ??") in this
lines..
I'll remove them before commit in cvs but some answer will be helpfull
Comparing:
C:\Progetti\xorm-beta6\src\org\xorm\InterfaceInvocationHandler.java(old)
To: C:\Program
Files\xorm-beta6\src\org\xorm\InterfaceInvocationHandler.java(new)
====
====
127 <! // The transaction this object is operating within, or null
128 <! private TransactionImpl txn;
!> //sj777 An object doesn't need anymore a reference to the
transaction
!> //sj777 now it is managed by interfacemanager, it sounds like
better too
!> // The transaction this object is operating within, or null//sj777
commented out
!> //private TransactionImpl txn;//sj777 commented out
!>
!> //added relationship with InterfaceManager to //sj777
!> // preserve PersistenceManager wide uniquiness of objects with the
same id //sj777
!> // despite Transactional property and Transaction life span//sj777
!> private InterfaceManager im; //sj777 commented out
!> //sj777 new constructor added
!> //sj777 this constructor is used attach retrieved persistent
instance to InterfaceManager
!> //sj777 if one creates an object with a non null row it must be an
persistent object becouse
!> //sj777 it is retrivied from datastore,
!> //sj777 this method is usually called from when navigating a
collection
!> //sj777 or iteratig troug a a query results
!> //sj777 so the objects must be persistent, and so related to
PersistenceManager.
!> public InterfaceInvocationHandler(InterfaceManagerFactory factory,
ClassMapping mapping, Row row,InterfaceManager _im){
!> //sj777 calls default constructor
!> this(factory, mapping, row);
!> //sj777 sets the InterfaceManger that manages this instance
!> im=_im;
!> //notifies the InterfaceManger to manage this instance
!> im.manage((InterfaceInvocationHandler)this);
!> }
172 <! if (txn != null) {
!> //if (txn != null) {//sj777 old one
!> //sj777 what's happen if this method is called on a transient
instance?? wich isn't related
!> //sj777 to an instance Manager?
!> //sj777 i think that i'll move any change, and possibly any
access to
!> //sj777 jdostate out of non jpo spec methods... (TODO)
!> //sj777 this method should only be used to the values, the
state must
!> //sj777 be changed elsewhere, more clean and consistently
!> if (im!=null&&im.currentTransaction()!=
null&&im.currentTransaction().isActive()) {//sj777 added to be more jdo
compliant
181 <! return (txn == null) ? null : (InterfaceManager)
txn.getPersistenceManager();
!> //return (txn == null) ? null : (InterfaceManager)
txn.getPersistenceManager();//sj777 anything to ask? :)
!> //sj777 we have passed from relationship with TransactionImpl
to relationship with IntrfaceManager
!> //sj777 so we can mantain identity outside transcation scope,
Any question? any suggestion? any sleep(1.35 am)?
!> return im; //sj777 added: now InterfaceInvocationHandelr is
!> //directly associated to the PersistenceManager alias
InterfaceManager
!> if ((im!=null) &&(im!=mgr))throw new
JDOUserException();//sj777An object is bound to its PersistentManager..
!> //sj777 todo implement Persistent non-transactional behaveour
205 <! * This is the only method where the txn field gets set.
!> //sj777 outdated comment* This is the only method where the txn
field gets set.
211 <! this.txn = txn;
212 <! txn.attach(proxy);
!> if ((im!=null)&&txn!=im.currentTransaction()) throw new
JDOUserException();//sj777 transaction and persistence manager are strictly
bound in jdo specs
!> //this.txn = txn;//sj777 commented out
!> txn.attach(proxy);//sj777 this is right a transaction must know
wich objects she uses and it can also attach transient objects
!> //sj777 todo must refresh
!> //sj777 but we have maked reacheble objects
transactional..
!> //sj777 it's consistent?!?.. wes help
!> else throw new JDOUserException(); //sj777 see JDO spec
239 <! boolean retainValues = txn.getRetainValues();
!> //boolean retainValues = txn.getRetainValues();//sj777 old line
!> boolean retainValues =
getInterfaceManager().currentTransaction().getRetainValues();//sj777
270 <! txn = null;
!> im.stopManaging(this);//sj777
!> im=null;//sj777
!> // txn = null;//sj777
297 <! txn = null;
!> im.stopManaging(this);
!> im=null;
!> ///txn = null;//sj777
!> case STATUS_PERSISTENT_NONTRANSACTIONAL://sj777 todo we must
still put somewhere refresh..
!> if (isTransactional()&&im!= null &&
im.currentTransaction()!=null &&im.currentTransaction().isActive()) //sj777
!> enterTransaction((TransactionImpl)
im.currentTransaction());//sj777
336 <! if (txn != null && txn.isActive()) {
!> if (isTransactional()&&im!= null &&
im.currentTransaction()!=null &&im.currentTransaction().isActive()) {//sj777
are these controls redundat??
338 <! enterTransaction(txn);
!> enterTransaction((TransactionImpl)
im.currentTransaction());//sj777
346 <! if (txn != null) {
!> //if (txn != null) {//sj777 old
!>
!> if (isTransactional()&&im!= null //sj777 new
!> && im.currentTransaction()!=null //sj777 new
!> &&im.currentTransaction().isActive()){//sj777 new
356 <! public void makePersistent(InterfaceManager mgr) {
357 <! if (txn != null) {
358 <! // Object was transactional already
359 <! if (mgr == txn.getInterfaceManager()) return;
!> void makePersistent(InterfaceManager mgr) {//sj777 this was public
why.. it looks like better now
!> //if (txn != null) {//sj777
!> if (isPersistent()&&im != null) {//sj777 new
!> // Object was transactional already//sj777?? old comment...
transactional != persistent
!> //objcet was persistent already//sj777 more
exact(persistent non transactional)
!> if (mgr == im) return;
!> //sj777 makePersistent can be called only inside a transaction
!> if (mgr.currentTransaction()==null //sj777 new
!> ||!mgr.currentTransaction().isActive())//sj777 new
!> throw new JDOUserException("makePersistent called outside an
active transaction context");//sj777
!> im=mgr;
!> mgr.manage(this);//sj777 and so the Persistence manager can
know who he manages
!> //sj777 todo the relationship must be connected to
the same mgr
!> //sj777 if it was created at transient time it can
be connected to
!> //sj777 null Manager
!> im.stopManaging(this);//sj777
!> im.manage(this);//sj777
!> return true;//sj777 it's my interpretation of jdo
specs
!> /**
572 <! refresh(txn.getInterfaceManager());
!> refresh(txn.getInterfaceManager());//sj777
!> */ //sj777
!> ///sj777 todo how tp implement for transient objects
without primary key?
!> return false;
667 <! refresh(txn.getInterfaceManager());
!> refresh(im);//sj777
670 <! txn = (TransactionImpl)
txn.getInterfaceManager().currentTransaction();
!> TransactionImpl txn = (TransactionImpl)
im.currentTransaction();//sj777
!> //sj777 what is the problem with this?
!> //sj777 why don't add a property for having refresh
only
!> //sj777 in concurrent enviroment
!> //
!> //sj777 i think that this must be optimized,
!> //sj777 too many get and put in maps.... TODOOOOOOOOOOOOO
735 <! other.makePersistent(txn.getInterfaceManager());
!> other.makePersistent(im);//sj777
767 <! if (txn != null && txn.isActive() && !isDirty()) {
!> //if (txn != null && txn.isActive() && !isDirty()) {//sj777 old
!> if (im!=null&&im.currentTransaction()!= null &&
im.currentTransaction().isActive() && !isDirty()&&isTransactional())
{//sj777 new
785 <! InterfaceManager mgr = null;
!> //sj777 now we have the InterfaceManager directly why don't
use it
!> /*InterfaceManager mgr = null;
788 <! }
789 <! rp = new RelationshipProxy(mgr, mapping, this,
!> }*/
!> //rp = new RelationshipProxy(mgr, mapping, this, ///sj777
old
!> rp = new RelationshipProxy(im, mapping, this, ///sj777 new
798 <! if (txn != null && txn.isActive()) {
799 <! txn.attachRelationship(rp);
!> //sj777 TODO move to before of internal cache use to
manage makePersistent calls
!> //sj777 and WES it look like that the check must be if
(isTransactional())???
!> //if (txn != null && txn.isActive()) {//sj777 old
!> if (im!=null&&im.currentTransaction()!= null &&
im.currentTransaction().isActive()) {//sj777 new
!>
((TransactionImpl)im.currentTransaction()).attachRelationship(rp);//sj777
new
863 <! txn.getInterfaceManager().refreshColumns(getRow(), dfg);
!> //txn.getInterfaceManager().refreshColumns(getRow(),
dfg);//sj777
!> im.refreshColumns(getRow(), dfg);//sj777
873 <! value = txn.getInterfaceManager()
874 <! .lookup(returnTypeMapping, value);
!> //value = txn.getInterfaceManager()///sj777
!> value = im.lookup(returnTypeMapping, value);//sj777
!> private void check(String currentMethod){
!> //return;
!>
if(!lastCheck&&(primaryKey!=null&&(row==null||!primaryKey.equals(row.getPrim
aryKeyValue()))||
!>
(row!=null&&row.getPrimaryKeyValue()!=null&&!row.getPrimaryKeyValue().equals
(primaryKey)))){
!> synchronized(System.out){
!> System.out.println("ATTENZIONE");
!> System.out.println("row.getPrimaryKeyValue
!=priamaryKey:"+ mapping.getMappedClass());
!> if(primaryKey!=null)
!> System.out.println("primaryKey "+ primaryKey+"
classe: "+primaryKey.getClass().getName());
!> else
!> System.out.println("primaryKey "+ primaryKey+" ");
!>
!> if(row!=null)
!> if (row.getPrimaryKeyValue()!=null)
!> System.out.println("row.getPrimaryKeyValue "+
row.getPrimaryKeyValue()+" nuova classe:
"+row.getPrimaryKeyValue().getClass().getName());
!> else
!> System.out.println("row.getPrimaryKeyValue==null");
!> else
!> System.out.println("row==null");
!>
!> System.out.println("metodo precedente:
"+methodName);
!> System.out.println("metodo attuale:
"+currentMethod);
!> }
!> }
!>
lastCheck=(primaryKey!=null&&(row==null||!primaryKey.equals(row.getPrimaryKe
yValue()))||(row!=null&&row.getPrimaryKeyValue()!=null&&!row.getPrimaryKeyVa
lue().equals(primaryKey)));
!> if
(row!=null&&row.getPrimaryKeyValue()!=null&&(!row.getPrimaryKeyValue().equal
s(lastRowVal))){
!> synchronized(System.out){
!> System.out.println("ATTENZIONE");
!> System.out.println("row.getPrimaryKeyValue cambiata
in:"+ mapping.getMappedClass());
!> if (lastRow==null)System.out.println("lastRow==null");
!> else if (lastRowVal!=null)
!> System.out.println("row.getPrimaryKeyValue
vecchia"+ lastRowVal+" vecchia classe: "+lastRowVal.getClass().getName());
!> else
!> System.out.println("primaryKey vecchia"+
lastRowVal+" ");
!>
!> if(row!=null)
!> if (row.getPrimaryKeyValue()!=null)
!> System.out.println("row.getPrimaryKeyValue nuova"+
row.getPrimaryKeyValue()+" nuova classe:
"+row.getPrimaryKeyValue().getClass().getName());
!> else
!> System.out.println("row.getPrimaryKeyValue==null");
!> else
!> System.out.println("row==null");
!> System.out.println("metodo precedente:
"+methodName);
!> System.out.println("metodo attuale:
"+currentMethod);
!> }
!> }
!> if (primaryKey!=null&&!primaryKey.equals(lastVal)){
!> synchronized(System.out){
!> System.out.println("ATTENZIONE");
!> System.out.println("primaryKey cambiata in:"+
mapping.getMappedClass());
!> if (lastVal!=null)
!> System.out.println("primaryKey vecchia"+ lastVal+"
vecchia classe: "+lastVal.getClass().getName());
!> else
!> System.out.println("primaryKey vecchia"+ lastVal+"
");
!> if(primaryKey!=null)
!> System.out.println("primaryKey nuova"+ primaryKey+"
nuova classe: "+primaryKey.getClass().getName());
!> else
!> System.out.println("primaryKey nuova"+ primaryKey+"
");
!> System.out.println("metodo precedente: "+methodName);
!> System.out.println("metodo attuale: "+currentMethod);
!> }
!>
!> }
!> methodName=currentMethod;
!> lastVal=primaryKey;
!> lastRowVal=(row==null)?null:row.getPrimaryKeyValue();
!> lastRow=row;
!>
!> }
!>
!> private String methodName="";
!> private Object lastVal=null;
!> private Object lastRowVal=null;
!> private Object lastRow=null;
!> private boolean lastCheck=false;
|