Re: AW: AW: Forgot subject: Strange Could not locate metadata for the classError?
Hans- 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. Yes, it should. You might want to print out the System.identityHashCode(broker) to be sure, but it looks like this will replicate the transaction association logic that we perform automatically in a JEE5 environment. So does the requirement to set the multithreaded property remain by this usage scenario? No, not so long as a single Broker is ever used by a single thread (which should be the case as long as the same JTA transaction is not used from multiple threads). On Mar 24, 2007, at 12:45 AM, Hans J. Prueller wrote: 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?
[jira] Commented: (OPENJPA-176) Exception prefixes should be human-readable
[ https://issues.apache.org/jira/browse/OPENJPA-176?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12483852 ] Michael Dick commented on OPENJPA-176: -- It looks like we just use type + error if the type isn't recognized. +1 as it is, but I'm not opposed to changing type + error to unexpected error or something similar. Exception prefixes should be human-readable --- Key: OPENJPA-176 URL: https://issues.apache.org/jira/browse/OPENJPA-176 Project: OpenJPA Issue Type: Improvement Components: diagnostics Affects Versions: 0.9.0, 0.9.6 Reporter: Marc Prud'hommeaux Assigned To: Marc Prud'hommeaux Priority: Trivial Attachments: OPENJPA-176.patch OpenJPA prefixes all exception messages with a string of the form exception type|is fatal|version, restulting in strings like 4|false|0.9.6-incubating org.apache.openjpa.persistence.PersistenceException. This isn't very useful to the casual observer, since no translation of the meaning of the fields is done. it would be nice if we translated the fatal and type parameters, so that the string looked like user-error|recoverable|0.9.6-incubating. -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online.
[jira] Resolved: (OPENJPA-176) Exception prefixes should be human-readable
[ https://issues.apache.org/jira/browse/OPENJPA-176?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Marc Prud'hommeaux resolved OPENJPA-176. Resolution: Fixed Fix Version/s: 0.9.7 Implemented patch. Exception prefixes should be human-readable --- Key: OPENJPA-176 URL: https://issues.apache.org/jira/browse/OPENJPA-176 Project: OpenJPA Issue Type: Improvement Components: diagnostics Affects Versions: 0.9.0, 0.9.6 Reporter: Marc Prud'hommeaux Assigned To: Marc Prud'hommeaux Priority: Trivial Fix For: 0.9.7 Attachments: OPENJPA-176.patch OpenJPA prefixes all exception messages with a string of the form exception type|is fatal|version, restulting in strings like 4|false|0.9.6-incubating org.apache.openjpa.persistence.PersistenceException. This isn't very useful to the casual observer, since no translation of the meaning of the fields is done. it would be nice if we translated the fatal and type parameters, so that the string looked like user-error|recoverable|0.9.6-incubating. -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online.
Re: Shared classloader and subclasses
Abe White wrote: I see. Here's a proposal: in the MetaDataRepository's implementation of the RegisterClassListener interface, the repository only registers the given class if either the user has not specified a persistent types list (which we allow and in which case we attempt to lazily discover persistent types), or if the class name appears in the list. That way if you follow JPA guidelines and specify your persistent class list properly, subclasses left off the list won't even get registered with the metadata repository. That sounds about right. I tried something similar using MetaDataFactory.getPersistentTypeNames(), but this method requires a classloader to be passed to it. Using the thread's classloader didn't seem right (and didn't work anyway). Is there another way to find this list? Good point. I guess we can't exclude the classes in the register class listener method itself, but we can do so when we processRegisteredClasses(). This method is only ever called from places where we have the proper classloader (the same one we pass to getPersistentTypeNames()). This works for me :) Here's a patch for 0.9.6 source. I've gone for the simplest solution, but it might be improved by looping over pcNames instead of _registered (?). http://www.nabble.com/file/7398/openjpa-diff openjpa-diff Index: MetaDataRepository.java === --- MetaDataRepository.java (.../tags/0.9.6/openjpa-kernel/src/main/java/org/apache/openjpa/meta) (revision 3) +++ MetaDataRepository.java (.../branches/0.9.6-ninthavenue/openjpa-kernel/src/main/java/org/apache/openjpa/meta) (working copy) @@ -302,7 +302,7 @@ return null; // check cache -processRegisteredClasses(); +processRegisteredClasses(envLoader); List classList = (List) _aliases.get(alias); // multiple classes may have been defined with the same alias: we @@ -928,7 +928,7 @@ } // check cache -processRegisteredClasses(); +processRegisteredClasses(envLoader); Class cls = (Class) _oids.get(oid.getClass()); if (cls != null) return getMetaData(cls, envLoader, mustExist); @@ -944,7 +944,7 @@ // if still not match, register any classes that look similar to the // oid class and check again resolveIdentityClass(oid); -if (processRegisteredClasses().length 0) { +if (processRegisteredClasses(envLoader).length 0) { cls = (Class) _oids.get(oid.getClass()); if (cls != null) return getMetaData(cls, envLoader, mustExist); @@ -1262,7 +1262,7 @@ * Parses the metadata for all registered classes. */ private void loadRegisteredClassMetaData(ClassLoader envLoader) { -Class[] reg = processRegisteredClasses(); +Class[] reg = processRegisteredClasses(envLoader); for (int i = 0; i reg.length; i++) { try { getMetaData(reg[i], envLoader, false); @@ -1276,7 +1276,7 @@ /** * Updates our datastructures with the latest registered classes. */ -Class[] processRegisteredClasses() { +Class[] processRegisteredClasses(ClassLoader envLoader) { if (_registered.isEmpty()) return EMPTY_CLASSES; @@ -1289,9 +1289,18 @@ } Collection failed = null; +Collection pcNames = getPersistentTypeNames(false, envLoader); for (int i = 0; i reg.length; i++) { try { -processRegisteredClass(reg[i]); + +/* + * Only process classes known to this MetaDataRepository, + * since _registered contains all classes loaded by + * PCRegistry. + */ +if (pcNames.contains(reg[i].getName())) { +processRegisteredClass(reg[i]); +} } catch (Throwable t) { if (!_conf.getRetryClassRegistration()) throw new MetaDataException(_loc.get(error-registered, Index: ClassMetaData.java === --- ClassMetaData.java (.../tags/0.9.6/openjpa-kernel/src/main/java/org/apache/openjpa/meta) (revision 4) +++ ClassMetaData.java (.../branches/0.9.6-ninthavenue/openjpa-kernel/src/main/java/org/apache/openjpa/meta) (working copy) @@ -309,7 +309,7 @@ if (_owner != null) return _repos.EMPTY_CLASSES; -_repos.processRegisteredClasses(); +_repos.processRegisteredClasses(getEnvClassLoader()); if (_subs == null) { Collection subs = _repos.getPCSubclasses(_type); _subs = (Class[]) subs.toArray(new Class[subs.size()]); -- View this message in context: http://www.nabble.com/Shared-classloader-and-subclasses-tf3431312.html#a9655900 Sent from the