I'm not sure if all of you know, but we are utilizing OpenJPA within a J2EE1.4 container for EJB3 migration purposes. In this "special" case we are using JPA in "application managed" mode but with synchronized JTA transactions of the container.
the current implementation holds a single EMF as a static member in memory for the whole JVM (there is definitely only 1 VM currently running) and every SLSB method called starts with creating a new EntityManager ... here is a code I think Patrick suggested to ensure synchronization of the EM with the JTA tx of the container: final BrokerFactory bf = OpenJPAPersistence.toBrokerFactory(emf); // the broker is part of a JTA managed tx // look for an existing Broker on the tx final Broker b = bf.newBroker(bf.getConfiguration() .getConnectionUserName(), bf.getConfiguration() .getConnectionPassword(), true, bf.getConfiguration().getConnectionRetainModeConstant(), true); // do some JPA configuration setup. Logic stolen from // EntityManagerFactoryImpl. b.setAutoDetach(AutoDetach.DETACH_CLOSE, true); b.setAutoDetach(AutoDetach.DETACH_ROLLBACK, true); b.setDetachedNew(false); return OpenJPAPersistence.toEntityManager(b); If I understand it right - above lookup code will ensure that there is only a single EM within a JTA transaction even if I call the method several times from several methods within the TX. So does the requirement to set the "multithreaded" property remain by this usage scenario? Hans > -----Ursprüngliche Nachricht----- > Von: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] > Gesendet: Freitag, 23. März 2007 23:46 > An: open-jpa-dev@incubator.apache.org > Betreff: Re: AW: Forgot subject: Strange Could not locate metadata for the > classError? > > >>> Marc Prud'hommeaux wrote: > >>> > >>>> Hans- > >>>> I don't see how the error could be data-related. > >>>> One thing: if you are using the same EMF from multiple threads, > >>>> do you have the "openjpa.Multithreaded" property explicitly > >>>> set to "true" in your persistence.xml (or however you are > >>>> configuring the EMF)? > > > Just to make sure there is no confusion. What I think Marc meant was > "using the same EM from multiple threads". The openjpa.Multithreading > property should not apply to multiple threads accessing the > EntityManagerFactory, which is always thread-safe. The property > should refer to multiple threads accessing the same EntityManager, > which is not thread-safe by default. > > Craig > > On Mar 23, 2007, at 2:56 PM, Marina Vatkina wrote: > > > Marc, > > > > No, in GlassFish (GF) it shouldn't be the case, but there could be > > more than 1 EMF created at the same time. The test case uses > > stateless session bean for accessing EM, so there is no guarantee > > that the same bean instance serves the 1st method (with a > > successful persist) and the 2nd (with a failed query). But what's > > worth noting, that in both cases, mine and Hans's it's the query > > that causes the problems). > > > > BTW, I need to test again without tracing - it can slow things down > > and hide the problem. > > > > regards, > > -marina > > > > Marc Prud'hommeaux wrote: > >> Marina- > >> In a normal J2EE app, the same EntityManager will never be used > >> concurrently from multiple threads. That might also be the case > >> in your environment, but it would be interesting to see if the > >> problem ever crops up after you enable this property. > >> On Mar 23, 2007, at 2:36 PM, Marina Vatkina wrote: > >>> Marc, > >>> > >>> Does OpenJPA figures out by itself that it is running in a > >>> multithreaded environment when used in an app- or web-server? Or > >>> do you expect users to always specify this setting when they > >>> decide to deploy it to a multi-threaded container? > >>> > >>> thanks, > >>> -marina > >>> > >>> Marc Prud'hommeaux wrote: > >>> > >>>> Hans- > >>>> I don't see how the error could be data-related. > >>>> One thing: if you are using the same EMF from multiple threads, > >>>> do you have the "openjpa.Multithreaded" property explicitly > >>>> set to "true" in your persistence.xml (or however you are > >>>> configuring the EMF)? Failure to do this means that access to > >>>> the broker is unsynchronized, and I can see how it might lead > >>>> to a problem like this. > >>>> On Mar 23, 2007, at 11:46 AM, Hans J. Prueller wrote: > >>>> > >>>>> hm.. sounds strange. could it bet he case that the error > >>>>> message openjpa is > >>>>> printing is only a subsequent error of another one below/before? > >>>>> > >>>>> as the JNDI binding did not really work (as you can remember: > >>>>> everytime I am > >>>>> accessing the EMF from JNDI it is initialized again and again) > >>>>> so I did a > >>>>> quick-and-dirty solution for the PoC of OpenJPA integration: > >>>>> I saved the EMF > >>>>> as a static field instead to JNDI, i.e. the first time it is > >>>>> accessed it is > >>>>> created - then every client throughout my app should access > >>>>> the same static > >>>>> EMF instance. As there is definitely only a single JVM this > >>>>> shouldn't make > >>>>> problems I suggest... > >>>>> > >>>>> Additionally I did not see any data in the logs that is > >>>>> indicating that a > >>>>> second EMF is initialized or sth. like that. The strange thing > >>>>> is that it > >>>>> worked several invocations before and after .. could it be a > >>>>> data- related > >>>>> problem? Anyway, I was not able to reproduce the error.... > >>>>> > >>>>> Hans > >>>>> > >>>>> > >>>>> > >>>>> > >>>>>> -----Ursprüngliche Nachricht----- > >>>>>> Von: Marc Prud'hommeaux [mailto:[EMAIL PROTECTED] Im > >>>>>> Auftrag von > >>>>>> Marc Prud'hommeaux > >>>>>> Gesendet: Freitag, 23. März 2007 17:59 > >>>>>> An: open-jpa-dev@incubator.apache.org > >>>>>> Betreff: Re: Forgot subject: Strange Could not locate > >>>>>> metadata for the > >>>>>> classError? > >>>>>> > >>>>>> Hans- > >>>>>> > >>>>>> There are only two possible conditions in which I can see this > >>>>>> problem happening: > >>>>>> > >>>>>> 1. the class "com.lbslogics.ims.model.PositionLog" is not > >>>>>> loadable in > >>>>>> the current environment's classloader. > >>>>>> 2. the PositionLog class was registered with the > >>>>>> MetaDataRepository > >>>>>> during the lookup process. > >>>>>> > >>>>>> Since the same code has been executed hundreds of times via > >>>>>> the MDB > >>>>>> prior to this error, neither of these seems very plausible. > >>>>>> Are you > >>>>>> sure that the exact same EntityManagerFactory (in the same > >>>>>> JVM) has > >>>>>> been used prior to this error to execute the same method? The > >>>>>> fact > >>>>>> that it looks like we are parsing the query for the first > >>>>>> time (since > >>>>>> it appears we are making a new internal parse compilation from > >>>>>> it) > >>>>>> makes it look like that particular method has not yet been > >>>>>> called for > >>>>>> that EntityManager's EntityManagerFactory. > >>>>>> > >>>>>> If this is something you can reproduce, it would be > >>>>>> interesting if we > >>>>>> could see more logging output (enabled by setting the "kodo.Log" > >>>>>> property to "DefaultLevel=TRACE"), especially those messages > >>>>>> that are > >>>>>> on the MetaData channel. > >>>>>> > >>>>>> > >>>>>> > >>>>>> On Mar 23, 2007, at 5:57 AM, Hans J. Prueller wrote: > >>>>>> > >>>>>>> full stack trace (up until application specific stuff) is: > >>>>>>> > >>>>>>> 2007-03-22 21:34:53,287 : SEVERE : WorkThread-2/34 : > >>>>>>> Logger.log : > >>>>>>> system exception in business method: > >>>>>>> <4|true|0.9.7-incubating-SNAPSHOT> > >>>>>>> org.apache.openjpa.persistence.ArgumentException: Could not > >>>>>>> locate > >>>>>>> metadata for the class using alias "PositionLog". Registered > >>>>>>> alias > >>>>>>> mappings: "{PositionLog=[class > >>>>>>> com.lbslogics.ims.model.PositionLog]}" > >>>>>>> at > >>>>>>> org.apache.openjpa.meta.MetaDataRepository.getMetaData > >>>>>>> (MetaDataRepository.java:345) > >>>>>>> at > >>>>>>> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getClassMet > >>>>>>> aD at a( > >>>>>>> JPQLExpressionBuilder.java:164) > >>>>>>> at > >>>>>>> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.resolveClas > >>>>>>> sM et aD > >>>>>>> ata(JPQLExpressionBuilder.java:142) > >>>>>>> at > >>>>>>> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getCandidat > >>>>>>> eM et aD > >>>>>>> ata(JPQLExpressionBuilder.java:211) > >>>>>>> at > >>>>>>> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getCandidat > >>>>>>> eM et aD > >>>>>>> ata(JPQLExpressionBuilder.java:181) > >>>>>>> at > >>>>>>> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getCandidat > >>>>>>> eT yp e( > >>>>>>> JPQLExpressionBuilder.java:174) > >>>>>>> at > >>>>>>> org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.access > >>>>>>> $500(JPQLExpressionBuilder.java:61) > >>>>>>> at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder > >>>>>>> $ParsedJPQL.populate(JPQLExpressionBuilder.java:1668) > >>>>>>> at > >>>>>>> org.apache.openjpa.kernel.jpql.JPQLParser.populate > >>>>>>> (JPQLParser.java:52) > >>>>>>> at > >>>>>>> org.apache.openjpa.kernel.ExpressionStoreQuery.populateFromCompi > >>>>>>> la ti on > >>>>>>> (ExpressionStoreQuery.java:145) > >>>>>>> at > >>>>>>> org.apache.openjpa.datacache.QueryCacheStoreQuery.populateFromCo > >>>>>>> mp il at > >>>>>>> ion(QueryCacheStoreQuery.java:237) > >>>>>>> at > >>>>>>> org.apache.openjpa.kernel.QueryImpl.newCompilation > >>>>>>> (QueryImpl.java: 644) > >>>>>>> at > >>>>>>> org.apache.openjpa.kernel.QueryImpl.compilationFromCache > >>>>>>> (QueryImpl.java:625) > >>>>>>> at > >>>>>>> org.apache.openjpa.kernel.QueryImpl.compileForCompilation > >>>>>>> (QueryImpl.java:591) > >>>>>>> at > >>>>>>> org.apache.openjpa.kernel.QueryImpl.compileForExecutor > >>>>>>> (QueryImpl.java:653) > >>>>>>> at org.apache.openjpa.kernel.QueryImpl.compile > >>>>>>> (QueryImpl.java:560) > >>>>>>> at > >>>>>>> org.apache.openjpa.persistence.EntityManagerImpl.createNamedQuer > >>>>>>> y > >>>>>>> (EntityManagerImpl.java:785) > >>>>>>> at > >>>>>>> org.apache.openjpa.persistence.EntityManagerImpl.createNamedQuer > >>>>>>> y > >>>>>>> (EntityManagerImpl.java:62) > >>>>>>> at > >>>>>> > >>>>>> > >>>>>> com.lbslogics.ims.model.PositionLog.findById(PositionLog.java: > >>>>>> 175) > >>>>>> > >>>>>>> at > >>>>>>> com.lbslogics.ims.persistence.ejb.EventBean.getPositionLog > >>>>>>> (EventBean.java:2875) > >>>>>>> [ ... some more ] > >>>>>>> > >>>>>>> The corresponding EventBean is a SLSB (EJB2.1) and the > >>>>>>> method looks > >>>>>>> like > >>>>>>> that: > >>>>>>> > >>>>>>> /** > >>>>>>> * > >>>>>>> * @return > >>>>>>> */ > >>>>>>> public PositionLog getPositionLog(final EntityManager em) { > >>>>>>> final PositionLog log = PositionLog.findById(em, > >>>>>> > >>>>>> > >>>>>> getPositionLogId > >>>>>> > >>>>>>> ()); > >>>>>>> return log; > >>>>>>> } > >>>>>>> > >>>>>>> and the Positionlog.findById is a static method which > >>>>>>> encapsulates > >>>>>>> some > >>>>>>> of the "technical work": > >>>>>>> > >>>>>>> public static PositionLog findById(EntityManager em, > >>>>>>> Long > >>>>>>> plId) > >>>>>>> { > >>>>>>> Query q = em.createNamedQuery("PositionLog.byId"); > >>>>>>> q.setParameter("id", plId); > >>>>>>> > >>>>>>> try { > >>>>>>> return (PositionLog) q.getSingleResult(); > >>>>>>> } catch (javax.persistence.NoResultException e) { > >>>>>>> logger.finest("findById: did not find result for > >>>>> > >>>>> > >>>>> id=" + > >>>>> > >>>>>> plId); > >>>>>> > >>>>>>> return null; > >>>>>>> } > >>>>>>> } > >>>>>>> > >>>>>>> This method or better the top-level entry point of this > >>>>>>> method is > >>>>>>> called > >>>>>>> several hundred times for different records, all invoked by a > >>>>>>> MDB. > >>>>>>> Could > >>>>>>> it be some concurrency issue because after several hundred > >>>>>>> invocations > >>>>>>> only a single exception occured? > >>>>>>> > >>>>>>> Hans > >>>>>>> > >>>>>>> Am Freitag, den 23.03.2007, 05:48 -0700 schrieb Patrick Linskey: > >>>>>>> > >>>>>>>> Could you post the full stack trace, and maybe some code > >>>>>>>> showing how > >>>>>>>> you're invoking the JPA APIs? > >>>>>>>> > >>>>>>>> -Patrick > >>>>>>>> > >>>>> > >>> > > > > Craig Russell > Architect, Sun Java Enterprise System http://java.sun.com/products/jdo > 408 276-5638 mailto:[EMAIL PROTECTED] > P.S. A good JDO? O, Gasp!