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; |