Hi Gus, I think all works as designed here. you have some persistent object "data" that was persisted at some time before calling the prepareTX method.
being a PersistenceCapable Object data still has its old PersistenceManager. If you use a new PM to open a transaction, data is still connected to its original PM which has no open transaction. That's why you get the Exception "javax.jdo.JDOUserException: Transaction is not active.". So IMO you solution to use the original PM is not a "workaround", but just the right thing to do! cheers, Thomas > -----Original Message----- > From: Gus Heck [mailto:[EMAIL PROTECTED] > Sent: Monday, December 08, 2003 7:50 PM > To: OJB Users List > Subject: Re: JDO Bug (status please) > > > Yes I seem to have confirmed that it is a problem with > getting the wrong > Persistence Manager. I changed PrepareTX() to look like this: > > private TXData prepareTX() { > TXData td = new TXData(); > td.pm = > ((javax.jdo.spi.PersistenceCapable)data).jdoGetPersistenceManager(); > if (td.pm == null) { > td.pm = > PersistenceHelper.getPMF().getPersistenceManager(); > } > td.tx = td.pm.currentTransaction(); > //System.out.println("1 tx.isAcitve():"+td.tx.isActive()); > td.tx.begin(); > //System.out.println("2 tx.isAcitve():"+td.tx.isActive()); > return td; > } > > and I get this output: > > 3 tx.isActive():true > PM for tx:[EMAIL PROTECTED] > PM for data:[EMAIL PROTECTED] > > And the database is successfully updated. So now there is a > workaround, > which is a huge improvement, but casting to > PersistenceCapable shouldn't > be needed... > > -Gus > > Gus Heck wrote: > > > Hi, > > > > First of all, Thanks! :) I have pluged it into my code and I am > > getting getting further, but then I get an error. I don't > know if it > > is my fault or a bug, though. Here is what I am doing: > > > > I have a class that wraps my persistant object and handles > all the JDO > > stuff so that the rest of the program doesn't have to know anything > > about JDO. It has these methods (among others) > > > > private TXData prepareTX() { > > TXData td = new TXData(); > > td.pm = PersistenceHelper.getPMF().getPersistenceManager(); > > td.tx = td.pm.currentTransaction(); > > //System.out.println("1 tx.isAcitve():"+td.tx.isActive()); > > td.tx.begin(); > > //System.out.println("2 tx.isAcitve():"+td.tx.isActive()); > > return td; > > } > > private void commitTX(TXData td) { > > td.tx.commit(); > > // I used to do td.pm.close() but that seemed to > > // give me errors saying PM was closed. > > } > > public void setCity(String city) { > > if (JDOHelper.isPersistent(this.data)) { > > TXData td = prepareTX(); > > System.out.println("3 tx.isActive():"+td.tx.isActive()); > > System.out.println("PM for > > tx:"+td.tx.getPersistenceManager()); > > System.out.println("PM for > > > data:"+((javax.jdo.spi.PersistenceCapable)data).jdoGetPersiste > nceManager()); > > > > data.setCity(city); > > commitTX(td); > > } else { > > data.setCity(city); > > } > > } > > > > I am getting this errror: > > > > at > > > org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run( > ThreadPool.java:619) > > > > at java.lang.Thread.run(Thread.java:534) > > Caused by: javax.jdo.JDOUserException: Transaction is not active. > > at > > com.sun.jdori.common.state.LifeCycleState.assertTransaction(Unknown > > Source) > > at > > > com.sun.jdori.common.state.PersistentNonTransactional.transiti > onWriteField(Unknown > > Source) > > at > > > com.sun.jdori.common.state.StateManagerImpl.prepareSetField2(Unknown > > Source) > > at > > com.sun.jdori.common.state.StateManagerImpl.prepareSetField(Unknown > > Source) > > at > > com.sun.jdori.common.state.StateManagerImpl.setStringField(Unknown > > Source) > > at > org.cs101.fdb.impl.jdo.LocationBase.jdoSetcity(LocationBase.java) > > at > org.cs101.fdb.impl.jdo.LocationBase.setCity(LocationBase.java:122) > > at > org.cs101.fdb.impl.jdo.LocationImpl.setCity(LocationImpl.java:287) > > ... 44 more > > > > and this output: > > > > [JDO] DEBUG: OjbStoreConnector.begin: > connectionReadyForRelease=false > > 3 tx.isActive():true > > PM for tx:[EMAIL PROTECTED] > > PM for data:[EMAIL PROTECTED] > > > > So it looks like there is a problem with the PMF not giving me a PM > > that handles my object. (at least the wrapper is different) > Is the PM > > supposed to be a singleton? Maybe this has become broken? > > > > -Gus > > > > Thomas Mahler wrote: > > > >> Hi all, > >> > >> Good news! Thanks to Gus getting me started. I've fixed > this pita bug > >> at last! > >> > >> it's in CVS HEAD already. > >> > >> cu, > >> thomas > >> > >> Thomas Mahler wrote: > >> > >>> Hi Gus, > >>> > >>> > >>> Gus Heck wrote: > >>> > >>>> Well, since I am relatively stuck I peeked under the > hood and took > >>>> a stab at fixing this, based on the assumption that the > analysis in > >>>> the previous news group discussion of a missing state > manger is the > >>>> problem. > >>> > >>> > >>> > >>> > >>> thanks for helping! Yes I guess the missing state > managers are the > >>> problem. > >>> > >>>> After some thinking and lots of tracking back and forth > through OJB > >>>> persistence broker stuff and being generally confused > >>> > >>> > >>> > >>> > >>> :-) > >>> > >>>> I realized that the problem can't really be there... > That part is > >>>> also used by non-jdo implementations, and JDO specific > stuff must > >>>> reside in the o.a.o.jdori.sql classes. (duh, silly me) To do > >>>> anything involving a state manager outside of that package would > >>>> make ojb's persistence broker depend on the sun reference > >>>> implementation of JDO. (I suspect that is unacceptable ;) ). > >>> > >>> > >>> > >>> > >>> You are absolutely right. the problem must be fixed > inside the jdori > >>> package. > >>> > >>>> > >>>> I figure that we want to get the state manager set as early as > >>>> possible because it may be needed by any class that > handles the PC > >>>> objects generated in the extent. So the first place I could find > >>>> that one gets a handle on the results of an extent call was the > >>>> constructor for OJBExtent. (please tell me if there is an > >>>> earlier/better point to get to the results) > >>> > >>> > >>> > >>> > >>> That's exactly the correct attack point. The patch I had in mind > >>> does exactly what you have done: looping through all loaded > >>> instances an assigning the SM. > >>> > >>>> > >>>> I tried hacking the Constructor to look like this just > to see if it > >>>> fixed the problem: > >>>> > >>>> private Iterator iterator; > >>>> private Class clazz; > >>>> private PersistenceBroker broker; > >>>> > >>>> /** > >>>> * Constructor for OjbExtent. > >>>> */ > >>>> public OjbExtent(Class pClazz, PersistenceBroker pBroker) > >>>> { > >>>> clazz = pClazz; > >>>> System.out.println(pBroker.getClass()); > >>>> Criteria selectExtent = null; > >>>> Query q = QueryFactory.newQuery(clazz, selectExtent); > >>>> broker = pBroker; > >>>> RsIterator iter = (RsIterator) > >>>> broker.getIteratorByQuery(q); > >>>> > >>>> // cycle through the extent and give the objects > a statemanager > >>>> ArrayList temp = new ArrayList(); > >>>> while (iter.hasNext()) { > >>>> Object o = iter.next(); > >>>> Identity oid = new Identity(o, broker); > >>>> PersistenceCapable pc; > >>>> // theoretically this should never > happen, but... > >>>> if (o instanceof PersistenceCapable) { > >>>> pc = (PersistenceCapable) o; > >>>> } else { > >>>> throw new RuntimeException("OJBExents are > returning > >>>> classes " + > >>>> "that are not > javax.jdo.spi.PersistenceCapapble??"); > >>>> } > >>>> > >>>> // FIXME: > >>>> // Something of a Hack... The current > implementation of > >>>> JDO in OJB > >>>> // guarantees that this cast works, but I > don't think it is > >>>> // in any way guaranteed not to change. > >>>> PersistenceManagerImpl pm = (PersistenceManagerImpl) > >>>> pc.jdoGetPersistenceManager(); > >>>> StateManagerInternal sm = pm.findStateManager(pc); > >>>> pc.jdoReplaceStateManager(sm); > >>>> temp.add(pc); > >>>> } > >>>> iter.releaseDbResources(); > >>>> this.iterator = temp.iterator(); > >>>> } > >>>> > >>>> I never got to see if this had an effect though because > it caused a > >>>> very surprising NPE... pc.jdoGetPersistenceManager() is > returning > >>>> null. So not only do the objects not have a state manager, they > >>>> don't have a persistence manager! > >>> > >>> > >>> > >>> > >>> The objects are just loaded by the PB, so they have no PM yet. > >>> > >>>> Any clue how to address this?? I don't see any way to > generate and > >>>> supply a PersistenceManager for the object. > >>> > >>> > >>> > >>> > >>> Not really. As there is no documentation about the JDORI > internals > >>> available the only solution is to study the code of the JDORI > >>> default FOStore solution. > >>> > >>>> I have a feeling that there is some other place I should be > >>>> looking.... I feel like I don't yet understand how the > sun RI gets > >>>> diverted/configured into using the OJB backend.... That > seems like > >>>> another possible point of attack but I havn't found it yet. > >>>> > >>> > >>> I believe the point of attack is OK. we simply have to find a way > >>> obtain the needed hooks into the JDORI. this can be a > real pita. But > >>> it will work in the end :-) > >>> > >>> (can you imagine what a hard job it was to write the > whole plugin? > >>> It took me long, long days of debugging through the JDORI. But in > >>> the end the coding itself took only a few hours.) > >>> > >>> I will review your patch this weekend. So I hope we get > you started > >>> by next week! > >>> > >>> thanks for your patience and also for sharing your patch! > >>> > >>> - thomas > >>> > >>>> -Gus > >>>> > >>>> Mahler Thomas wrote: > >>>> > >>>>> Hi Gus, > >>>>> > >>>>> Yes, I hope to get my hands on the open JDO issues very soon! > >>>>> > >>>>> Thomas > >>>>> > >>>>> > >>>>> > >>>>>> -----Original Message----- > >>>>>> From: Gus Heck [mailto:[EMAIL PROTECTED] > >>>>>> Sent: Tuesday, December 02, 2003 7:59 PM > >>>>>> To: OJB Users List > >>>>>> Subject: Re: JDO Bug (status please) > >>>>>> > >>>>>> > >>>>>> I just got bit by this, despite the fact I had read > this thread. > >>>>>> I forgot and coded a method that asked if an object is > >>>>>> persistant, and if not caused it to get a new ID and > make itself > >>>>>> persistant. > >>>>>> > >>>>>> I noticed something interesting though.... I edited > and changed > >>>>>> an object, then inadvertently created a copy of it > because of the > >>>>>> ID aquisition issue I just described, but when I did another > >>>>>> extent to display a list of all items, both the old object and > >>>>>> the inadvertently created object were identical right > down to the > >>>>>> ID. Logging intto mysql and doing a select shows that > this is not > >>>>>> what has happened in the DB. So it looks like the transient > >>>>>> objects returned by the extent are still cached > objects and may > >>>>>> become modified without effecting the database. > >>>>>> > >>>>>> This means that data can appear to be written to the > database but > >>>>>> in fact is not! > >>>>>> > >>>>>> I hope you will have time to work on this very soon, > I'm digging > >>>>>> through the discussion referenced below and having trouble > >>>>>> picking out what exactly the work around is... If you > or someone > >>>>>> else could post a direct workaround for getting a list of all > >>>>>> objects of a class that are persistant it would help a lot. > >>>>>> > >>>>>> TIA, > >>>>>> Gus > >>>>>> > >>>>>> Mahler Thomas wrote: > >>>>>> > >>>>>> > >>>>> > >>>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > --------------------------------------------------------------------- > >>>> To unsubscribe, e-mail: [EMAIL PROTECTED] > >>>> For additional commands, e-mail: [EMAIL PROTECTED] > >>>> > >>>> > >>> > >>> > >>> > --------------------------------------------------------------------- > >>> To unsubscribe, e-mail: [EMAIL PROTECTED] > >>> For additional commands, e-mail: [EMAIL PROTECTED] > >>> > >>> > >> > >> > >> > --------------------------------------------------------------------- > >> To unsubscribe, e-mail: [EMAIL PROTECTED] > >> For additional commands, e-mail: [EMAIL PROTECTED] > >> > > > > > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: [EMAIL PROTECTED] > > For additional commands, e-mail: [EMAIL PROTECTED] > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
