Author: jrbauer
Date: Thu Apr 22 16:12:50 2010
New Revision: 936930
URL: http://svn.apache.org/viewvc?rev=936930&view=rev
Log:
OPENJPA-1613 Per JPA spec, OpenJPA should take the @Transient annotation into
account when making a default access determination. This commit includes test
code contributed by Simon Droscher.
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/RestrictedMetaDataRepository.java
(with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/AbstractSuperclass.java
(with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/SubclassPerson.java
(with props)
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestSubclassOfAbstractSuperclass.java
(with props)
Modified:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementWithMultiplePUs.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/ImplicitFieldAccessBase.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java
openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/RestrictedMetaDataRepository.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/RestrictedMetaDataRepository.java?rev=936930&view=auto
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/RestrictedMetaDataRepository.java
(added)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/RestrictedMetaDataRepository.java
Thu Apr 22 16:12:50 2010
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.enhance;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.apache.openjpa.meta.MetaDataRepository;
+
+/**
+ * A simple metadata repository wrapper which removes selected types
+ * from the set of names returned by getPersistentTypeNames.
+ * This MDR provides a simple method to skip extraneous and more important,
+ * purposefully erroneous classes during enhancement. This
+ * especially useful in the case where all pu's are enhanced generically,
+ * automatically picking up all entities in the classpath.
+ */
+...@suppresswarnings("serial")
+public class RestrictedMetaDataRepository extends MetaDataRepository {
+
+ private Set<String> _excludedTypes = new HashSet<String>();
+
+ public String getExcludedTypes() {
+ return _excludedTypes.toString();
+ }
+
+ public void setExcludedTypes(String types) {
+ StringTokenizer strTok = new StringTokenizer(types,",");
+ while (strTok.hasMoreTokens()) {
+ _excludedTypes.add(strTok.nextToken());
+ }
+ }
+
+ public Set<String> getPersistentTypeNames(boolean devpath, ClassLoader
envLoader) {
+ Set<String> types = super.getPersistentTypeNames(devpath, envLoader);
+ String[] typeArray = types.toArray(new String[types.size()]);
+ for (String type : typeArray) {
+ if(_excludedTypes.contains(type)) {
+ types.remove(type);
+ }
+ }
+ return types;
+ }
+}
Propchange:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/RestrictedMetaDataRepository.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementWithMultiplePUs.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementWithMultiplePUs.java?rev=936930&r1=936929&r2=936930&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementWithMultiplePUs.java
(original)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestEnhancementWithMultiplePUs.java
Thu Apr 22 16:12:50 2010
@@ -140,6 +140,14 @@ public class TestEnhancementWithMultiple
};
opts = new Options();
+ // Use a restricted mdr. This mdr will not hand out metadata for
excluded
+ // types. These are types that have known issues and should not be
enhanced.
+ // This test tries to enhance all persistent types in the classpath
and that
+ // can be problematic for tests which include entities that this test
should
+ // not attempt to enhance.
+ opts.setProperty("MetaDataRepository",
+
"org.apache.openjpa.enhance.RestrictedMetaDataRepository(excludedTypes=" +
+
"org.apache.openjpa.persistence.jdbc.annotations.UnenhancedMixedAccess)");
opts.put(PCEnhancer.class.getName() + "#bytecodeWriter", writer);
PCEnhancer.run(null, opts);
Modified:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/ImplicitFieldAccessBase.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/ImplicitFieldAccessBase.java?rev=936930&r1=936929&r2=936930&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/ImplicitFieldAccessBase.java
(original)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/ImplicitFieldAccessBase.java
Thu Apr 22 16:12:50 2010
@@ -28,7 +28,7 @@ import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
-import javax.persistence.Transient;
+// import javax.persistence.Transient;
/**
* Domain classes used by meta-model testing.
@@ -139,8 +139,10 @@ public class ImplicitFieldAccessBase ext
/** This method is annotated but transient to verify that placement of
* annotation does not confuse the determination of implicit access
* style of this class.
+ * OPENJPA-1613 - per spec and OpenJPA 1.x behavior, the Transient
annotation
+ * is now taken into consideration when making a default access
determination.
* */
- @Transient
+ // @Transient
public int getTransient() {
return 42;
}
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/AbstractSuperclass.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/AbstractSuperclass.java?rev=936930&view=auto
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/AbstractSuperclass.java
(added)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/AbstractSuperclass.java
Thu Apr 22 16:12:50 2010
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.simple;
+
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Transient;
+
+...@mappedsuperclass
+public abstract class AbstractSuperclass {
+
+ private String someProperty;
+
+ @Transient
+ public String getSomeProperty() {
+ return someProperty;
+ }
+
+ public void setSomeProperty(String prop) {
+ this.someProperty = prop;
+ }
+}
+
Propchange:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/AbstractSuperclass.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/SubclassPerson.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/SubclassPerson.java?rev=936930&view=auto
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/SubclassPerson.java
(added)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/SubclassPerson.java
Thu Apr 22 16:12:50 2010
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.simple;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+
+...@entity
+...@table(name="PERSON_SIMPLE")
+public class SubclassPerson extends AbstractSuperclass {
+ private int id;
+ private String forename;
+ private String surname;
+
+ @Id
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ @Basic
+ @Column(name = "FORENAME")
+ public String getForename() {
+ return forename;
+ }
+
+ public void setForename(String forename) {
+ this.forename = forename;
+ }
+
+ @Basic
+ @Column(name = "SURNAME")
+ public String getSurname() {
+ return surname;
+ }
+
+ public void setSurname(String surname) {
+ this.surname = surname;
+ }
+}
Propchange:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/SubclassPerson.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestSubclassOfAbstractSuperclass.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestSubclassOfAbstractSuperclass.java?rev=936930&view=auto
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestSubclassOfAbstractSuperclass.java
(added)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestSubclassOfAbstractSuperclass.java
Thu Apr 22 16:12:50 2010
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.simple;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+
+import junit.textui.TestRunner;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test persisting a class which has an abstract superclass.
+ */
+public class TestSubclassOfAbstractSuperclass
+ extends SingleEMFTestCase {
+
+ public void setUp() {
+ setUp(SubclassPerson.class);
+ }
+
+ public void testPersist() {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ em.persist(new SubclassPerson());
+ em.getTransaction().commit();
+ em.close();
+ }
+
+ public static void main(String[] args) {
+ TestRunner.run(TestPersistence.class);
+ }
+}
+
Propchange:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestSubclassOfAbstractSuperclass.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java?rev=936930&r1=936929&r2=936930&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java
(original)
+++
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java
Thu Apr 22 16:12:50 2010
@@ -127,7 +127,7 @@ public class PersistenceMetaDataDefaults
protected MemberFilter fieldFilter = new MemberFilter(Field.class);
protected MemberFilter methodFilter = new MemberFilter(Method.class);
- protected TransientFilter nonTransientFilter = new TransientFilter();
+ protected TransientFilter nonTransientFilter = new TransientFilter(false);
protected AnnotatedFilter annotatedFilter = new AnnotatedFilter();
protected GetterFilter getterFilter = new GetterFilter();
protected SetterFilter setterFilter = new SetterFilter();
@@ -344,7 +344,8 @@ public class PersistenceMetaDataDefaults
}
if (sup != null && !AccessCode.isUnknown(sup))
return sup.getAccessType();
-
+
+ trace(meta, _loc.get("access-default", meta,
AccessCode.toClassString(getDefaultAccessType())));
return getDefaultAccessType();
}
@@ -364,7 +365,7 @@ public class PersistenceMetaDataDefaults
getDeclaredFieldsAction(cls));
Method[] methods = AccessController.doPrivileged(
J2DoPrivHelper.getDeclaredMethodsAction(cls));
- List<Field> fields = filter(allFields, nonTransientFilter);
+ List<Field> fields = filter(allFields, new TransientFilter(true));
/*
* OpenJPA 1.x permitted private properties to be persistent. This is
* contrary to the JPA 1.0 specification, which states that persistent
@@ -374,15 +375,14 @@ public class PersistenceMetaDataDefaults
*/
getterFilter.setIncludePrivate(
conf.getCompatibilityInstance().getPrivatePersistentProperties());
- List<Method> getters = filter(methods, getterFilter,
- nonTransientFilter);
+ List<Method> getters = filter(methods, getterFilter);
if (fields.isEmpty() && getters.isEmpty())
return AccessCode.EMPTY;
fields = filter(fields, annotatedFilter);
getters = filter(getters, annotatedFilter);
- List<Method> setters = filter(methods, setterFilter);
+ List<Method> setters = filter(methods, setterFilter);
getters = matchGetterAndSetter(getters, setters);
boolean mixed = !fields.isEmpty() && !getters.isEmpty();
@@ -477,13 +477,24 @@ public class PersistenceMetaDataDefaults
Method[] publicMethods = AccessController.doPrivileged(
J2DoPrivHelper.getDeclaredMethodsAction(meta.getDescribedType()));
- List<Method> getters = filter(publicMethods, methodFilter,
+ /*
+ * OpenJPA 1.x permitted private accessor properties to be
persistent. This is
+ * contrary to the JPA 1.0 specification, which states that
persistent
+ * properties must be public or protected. OpenJPA 2.0+ will adhere
+ * to the specification by default, but provides a compatibility
+ * option to provide pre-2.0 behavior.
+ */
+ getterFilter.setIncludePrivate(
+
meta.getRepository().getConfiguration().getCompatibilityInstance().getPrivatePersistentProperties());
+
+ List<Method> getters = filter(publicMethods, methodFilter,
getterFilter,
ignoreTransient ? null : nonTransientFilter,
unknown || isProperty ? null : annotatedFilter,
explicit ? (isProperty ? null : propertyAccessFilter) : null);
- List<Method> setters = filter(publicMethods, setterFilter);
- return getters = matchGetterAndSetter(getters, setters);
+
+ List<Method> setters = filter(publicMethods, setterFilter);
+ return getters = matchGetterAndSetter(getters, setters);
}
return Collections.EMPTY_LIST;
@@ -553,7 +564,13 @@ public class PersistenceMetaDataDefaults
.getLog(OpenJPAConfiguration.LOG_RUNTIME);
log.warn(message.toString());
}
-
+
+ void trace(ClassMetaData meta, Localizer.Message message) {
+ Log log = meta.getRepository().getConfiguration()
+ .getLog(OpenJPAConfiguration.LOG_RUNTIME);
+ log.trace(message.toString());
+ }
+
@Override
protected List<String> getFieldAccessNames(ClassMetaData meta) {
return toNames(getPersistentFields(meta, false));
@@ -839,10 +856,20 @@ public class PersistenceMetaDataDefaults
}
/**
- * Selects all non-transient element.
+ * Selects non-transient elements. Selectively will examine only the
+ * transient field modifier.
*/
static class TransientFilter implements InclusiveFilter<AnnotatedElement> {
+ final boolean modifierOnly;
+
+ public TransientFilter(boolean modOnly) {
+ modifierOnly = modOnly;
+ }
+
public boolean includes(AnnotatedElement obj) {
+ if (modifierOnly) {
+ return !Modifier.isTransient(((Member)obj).getModifiers());
+ }
return !obj.isAnnotationPresent(Transient.class) &&
!Modifier.isTransient(((Member)obj).getModifiers());
}
Modified:
openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties?rev=936930&r1=936929&r2=936930&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties
(original)
+++
openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties
Thu Apr 22 16:12:50 2010
@@ -25,6 +25,9 @@ access-none: Property "{1}" in class "{0
access-unknown: Access style for "{0}" can not be determined.
access-no-property: No field or getter method for attribute "{1}" can be found
\
in "{0}".
+access-default: Access style for "{0}" can not be determined. The default
"{1}" will be used. \
+ If this access style is not correct, specify the correct style explicitly
on the \
+ persistent type or within the mapping file.
close-invoked: You have closed the EntityManager, though the persistence \
context will remain active until the current transaction commits.
no-managed-trans: There is no managed transaction in progress to sync this \
@@ -232,3 +235,4 @@ cache-retrieve-override: The setting of
null-detach: Can not detach null entity
override-named-query-lock-mode: Encountered a read lock level less than
LockModeType.READ when processing the \
NamedQuery {0} "{1}" in class "{2}". Setting query lock level to
LockModeType.READ.
+access-default: Access style for "{0}" can not be determined. The default
access of level of "{1}" will be used.