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]

Reply via email to