protected synchronized PersistenceBroker getBroker ( ) throws PBFactoryException { /* mkalen: NB! The loadProfileIfNeeded must be called _before_ acquiring a broker below, since some methods in PersistenceBrokerImpl will keep a local reference to the descriptor repository that was active during broker construction/refresh (not checking the repository beeing used on method invocation). PersistenceBrokerImpl#getClassDescriptor(Class clazz) is such a method, that will throw ClassNotPersistenceCapableException on the following scenario: (All happens in one thread only): t0: activate per-thread metadata changes t1: load, register and activate profile A t2: load object O1 witch collection proxy C to objects {O2} (C stores profile key K(A)) t3: close broker from t2 t4: load, register and activate profile B t5: reference O1.getO2Collection, causing C loadData() to be invoked t6: C calls getBroker broker B is created and descriptorRepository is set to descriptors from profile B t7: C calls loadProfileIfNeeded, re-activating profile A t8: C calls B.getCollectionByQuery t9: B gets callback (via QueryReferenceBroker) to getClassDescriptor the local descriptorRepository from t6 is used! => We will now try to query for {O2} with profile B (even though we re-activated profile A in t7) => ClassNotPersistenceCapableException Keeping loadProfileIfNeeded() at the start of this method changes everything from t6: t6: C calls loadProfileIfNeeded, re-activating profile A t7: C calls getBroker, broker B is created and descriptorRepository is set to descriptors from profile A t8: C calls B.getCollectionByQuery t9: B gets callback to getClassDescriptor, the local descriptorRepository from t6 is used => We query for {O2} with profile A => All good :-) */ if ( _perThreadDescriptorsEnabled ) { loadProfileIfNeeded ( ) ; } PersistenceBroker broker ; if ( getBrokerKey ( ) == null ) { /* arminw: if no PBKey is set we throw an exception, because we don't know which PB (connection) should be used. */ throw new OJBRuntimeException ( "Can't find associated PBKey. Need PBKey to obtain a valid" + "PersistenceBroker instance from intern resources." ) ; } // first try to use the current threaded broker to avoid blocking broker = PersistenceBrokerThreadMapping . currentPersistenceBroker ( getBrokerKey ( ) ) ; // current broker not found or was closed, create a intern new one if ( broker == null || broker . isClosed ( ) ) { broker = PersistenceBrokerFactory . createPersistenceBroker ( getBrokerKey ( ) ) ; // signal that we use a new internal obtained PB instance to read the // data and that this instance have to be closed after use _needsClose = true ; } return broker ; }
Acquires a broker instance . If no PBKey is available a runtime exception will be thrown .