This is an automated email from the ASF dual-hosted git repository.

struberg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openjpa.git

commit 1a287b267f86079aa79348e9d24f93469522d07a
Author: Mark Struberg <strub...@apache.org>
AuthorDate: Mon Jun 12 20:20:20 2023 +0200

    OPENJPA-2911 fix pcClearFields for mixed access subclassing
---
 .../org/apache/openjpa/enhance/PCEnhancer.java     |  5 +-
 .../org/apache/openjpa/meta/ClassMetaData.java     | 28 ++++-----
 .../openjpa/enhance/TestSubclassValidator.java     | 20 -------
 .../enhance/TestMixedAccessSubclassing.java        | 69 ++++++++++++++++++++++
 .../enhance/common/apps/MixedAccessPerson.java     | 67 +++++++++++++++++++++
 .../openjpa/persistence/meta/TestMetamodel.java    | 48 +++++++--------
 6 files changed, 175 insertions(+), 62 deletions(-)

diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
index ff7435884..beda0f2bc 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
@@ -5189,10 +5189,7 @@ public class PCEnhancer {
         // just do a subclass approach instead. But this is not a good option,
         // since it would sacrifice lazy loading and efficient dirty tracking.
         if (getRedefine() || isFieldAccess(fmd)) {
-            instructions.add(new FieldInsnNode(Opcodes.PUTFIELD,
-                                               
Type.getInternalName(fmd.getDeclaringType()),
-                                               fmd.getName(),
-                                               
Type.getDescriptor(fmd.getDeclaredType())));
+            putfield(instructions, fmd.getDeclaringType(), fmd.getName(), 
fmd.getDeclaredType());
         }
         else if (getCreateSubclass()) {
             // property access, and we're not redefining. invoke the
diff --git 
a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java 
b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
index 08483aa2c..655a3cf39 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
@@ -717,27 +717,27 @@ public class ClassMetaData
      * Sets the access type.
      */
     public void setAccessType(int type) {
-       if (type == _accessType || type == AccessCode.UNKNOWN)
-               return;
-       if (!AccessCode.isValidClassCode(type)) {
+        if (type == _accessType || type == AccessCode.UNKNOWN)
+            return;
+        if (!AccessCode.isValidClassCode(type)) {
             throw new IllegalArgumentException(_loc.get("access-type-invalid",
-                   this, AccessCode.toClassString(type)).getMessage());
-       }
-       if (_accessType != AccessCode.UNKNOWN) { // changing access type
-           _repos.getLog().trace(_loc.get("access-type-change",
-                   this, AccessCode.toClassString(type),
-                   AccessCode.toClassString(_accessType)).getMessage());
-       }
+                                                        this, 
AccessCode.toClassString(type)).getMessage());
+        }
+        if (_accessType != AccessCode.UNKNOWN) { // changing access type
+            _repos.getLog().trace(_loc.get("access-type-change",
+                                           this, 
AccessCode.toClassString(type),
+                                           
AccessCode.toClassString(_accessType)).getMessage());
+        }
         _accessType = type;
     }
 
     /**
-     * Asserts the the given field (which must belong to this receiver)
+     * Asserts the given field (which must belong to this receiver)
      * can be set to the given access code. If the field code is allowed,
-     * it may have the side-effect of changing the access code of this 
receiver.
+     * it may have the side effect of changing the access code of this 
receiver.
      */
     void mergeFieldAccess(FieldMetaData fmd, int fCode) {
-       setAccessType(AccessCode.mergeFieldCode(this, fmd, fCode));
+        setAccessType(AccessCode.mergeFieldCode(this, fmd, fCode));
     }
 
     /**
@@ -751,7 +751,7 @@ public class ClassMetaData
      * Affirms if attributes of this class use mixed access types.
      */
     public boolean isMixedAccess() {
-       return AccessCode.isMixed(_accessType);
+        return AccessCode.isMixed(_accessType);
     }
 
     /**
diff --git 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestSubclassValidator.java
 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestSubclassValidator.java
index 04d43ca1c..0e774c015 100644
--- 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestSubclassValidator.java
+++ 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/enhance/TestSubclassValidator.java
@@ -58,26 +58,6 @@ public class TestSubclassValidator extends SingleEMFTestCase 
{
         repos.setSourceMode(MetaDataModes.MODE_META);
 
         final Log log = conf.getLog(OpenJPAConfiguration.LOG_ENHANCE);
-/*
-
-        {
-            final BCClass bcClass = 
project.loadClass(Department.class.getName(), tempCl);
-            final ClassMetaData meta = 
repos.getMetaData(tempCl.loadClass(Department.class.getName()), tempCl, false);
-            PCSubclassValidator subclassValidator = new 
PCSubclassValidator(meta, bcClass, log, false);
-            subclassValidator.assertCanSubclass();
-        }
-
-        try {
-            final BCClass bcClass = 
project.loadClass(RuntimeTest2.class.getName(), tempCl);
-            final ClassMetaData meta = 
repos.getMetaData(tempCl.loadClass(RuntimeTest2.class.getName()), tempCl, 
false);
-            PCSubclassValidator subclassValidator = new 
PCSubclassValidator(meta, bcClass, log, true);
-            subclassValidator.assertCanSubclass();
-            fail("RuntimeTest2 validation should fail");
-        }
-        catch (UserException ue) {
-            // all fine
-        }
-*/
 
         {
             ClassNode classNode = 
AsmHelper.readClassNode(EnhanceableGetterEntity.class.getClassLoader(), 
EnhanceableGetterEntity.class.getName());
diff --git 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestMixedAccessSubclassing.java
 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestMixedAccessSubclassing.java
new file mode 100644
index 000000000..c59dfbc5c
--- /dev/null
+++ 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/TestMixedAccessSubclassing.java
@@ -0,0 +1,69 @@
+/*
+ * 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.enhance;
+
+import org.apache.openjpa.persistence.enhance.common.apps.MixedAccessPerson;
+import org.apache.openjpa.persistence.test.SingleEMTestCase;
+import org.junit.Test;
+
+/**
+ * Test subclass enhancement on the fly with mixed access strategy
+ *
+ * @author <a href="mailto:strub...@apache.org";>Mark Struberg</a>
+ */
+public class TestMixedAccessSubclassing extends SingleEMTestCase {
+
+    @Override
+    public void setUp() {
+        super.setUp(
+                "openjpa.RuntimeUnenhancedClasses", "supported",
+                "openjpa.DynamicEnhancementAgent", "false",
+                MixedAccessPerson.class);
+    }
+
+    @Test
+    public void testDynamicEnhancement() {
+        int pk = -1;
+        {
+            em.getTransaction().begin();
+            // step 1: create the person
+            MixedAccessPerson p = new MixedAccessPerson();
+            p.setFirstName("Han");
+            p.setLastName("Solo");
+            assertEquals("changed_Solo", p.getLastName());
+            em.persist(p);
+            em.flush();
+            pk = p.getId();
+            em.clear();
+            em.getTransaction().commit();
+        }
+
+        {
+            em.getTransaction().begin();
+            // step 2: read back the person
+            MixedAccessPerson p2 = em.find(MixedAccessPerson.class, pk);
+            assertNotNull(p2);
+
+            assertEquals(pk, p2.getId());
+            assertEquals("Han", p2.getFirstName());
+
+            // since we use property access the setter will get invoked again 
-> 2x changed_
+            assertEquals("changed_changed_Solo", p2.getLastName());
+            em.getTransaction().commit();
+        }
+    }
+}
diff --git 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/MixedAccessPerson.java
 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/MixedAccessPerson.java
new file mode 100644
index 000000000..64089ba34
--- /dev/null
+++ 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/enhance/common/apps/MixedAccessPerson.java
@@ -0,0 +1,67 @@
+/*
+ * 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.enhance.common.apps;
+
+import jakarta.persistence.Access;
+import jakarta.persistence.AccessType;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+
+/**
+ * Entity to test subclass enhancing with mixed access
+ * Note that this class will not be enhanced during the build!
+ *
+ * @author <a href="mailto:strub...@apache.org";>Mark Struberg</a>
+ */
+@Entity
+@Access(AccessType.FIELD)
+public class MixedAccessPerson {
+
+    @Id
+    @GeneratedValue
+    private int id;
+
+    private String firstName;
+
+    private String internalLastName;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    @Access(AccessType.PROPERTY)
+    public String getLastName() {
+        return internalLastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.internalLastName = lastName != null ? "changed_" + lastName : 
null;
+    }
+}
diff --git 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestMetamodel.java
 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestMetamodel.java
index 464f8731c..504a853b0 100644
--- 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestMetamodel.java
+++ 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/meta/TestMetamodel.java
@@ -60,24 +60,24 @@ public class TestMetamodel extends SingleEMFTestCase {
     @Override
     public void setUp() {
         if (model == null) {
-       super.setUp(
-               "openjpa.RuntimeUnenhancedClasses", "unsupported",
-               "openjpa.DynamicEnhancementAgent", "false",
-                       ImplicitFieldAccessMappedSuperclass.class,
-               ImplicitFieldAccessBase.class,
-               ImplicitFieldAccessSubclass.class,
-               ExplicitFieldAccess.class,
-               ExplicitPropertyAccess.class,
-               Embed0.class,
-               Embed1.class,
-               OneOneParent.class,
-               OneOneChild.class,
-               Book.class,
-               Library.class,
-               Page.class,
-               Address.class,
-               Geocode.class);
-       emf.createEntityManager();
+        super.setUp(
+                "openjpa.RuntimeUnenhancedClasses", "unsupported",
+                "openjpa.DynamicEnhancementAgent", "false",
+                ImplicitFieldAccessMappedSuperclass.class,
+                ImplicitFieldAccessBase.class,
+                ImplicitFieldAccessSubclass.class,
+                ExplicitFieldAccess.class,
+                ExplicitPropertyAccess.class,
+                Embed0.class,
+                Embed1.class,
+                OneOneParent.class,
+                OneOneChild.class,
+                Book.class,
+                Library.class,
+                Page.class,
+                Address.class,
+                Geocode.class);
+        emf.createEntityManager();
         model = (MetamodelImpl)emf.getMetamodel();
         }
     }
@@ -109,11 +109,11 @@ public class TestMetamodel extends SingleEMFTestCase {
     }
 
     public void testDomainClassCategorizedInPersistentCategory() {
-       assertCategory(PersistenceType.MAPPED_SUPERCLASS, 
ImplicitFieldAccessMappedSuperclass.class);
-       assertCategory(PersistenceType.ENTITY, ImplicitFieldAccessBase.class);
-       assertCategory(PersistenceType.ENTITY, 
ImplicitFieldAccessSubclass.class);
-       assertCategory(PersistenceType.EMBEDDABLE, Embed0.class);
-       assertCategory(PersistenceType.EMBEDDABLE, Embed1.class);
+        assertCategory(PersistenceType.MAPPED_SUPERCLASS, 
ImplicitFieldAccessMappedSuperclass.class);
+        assertCategory(PersistenceType.ENTITY, ImplicitFieldAccessBase.class);
+        assertCategory(PersistenceType.ENTITY, 
ImplicitFieldAccessSubclass.class);
+        assertCategory(PersistenceType.EMBEDDABLE, Embed0.class);
+        assertCategory(PersistenceType.EMBEDDABLE, Embed1.class);
 
         assertNotNull(model.entity(ImplicitFieldAccessBase.class));
         assertNotNull(model.entity(ImplicitFieldAccessSubclass.class));
@@ -401,7 +401,7 @@ public class TestMetamodel extends SingleEMFTestCase {
     }
 
     void assertCategory(PersistenceType category, Class<?> cls) {
-       assertEquals(cls.toString(), category, categorize(cls));
+        assertEquals(cls.toString(), category, categorize(cls));
     }
 
     Field getStaticField(Class<?> cls, String name) {

Reply via email to