You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by cu...@apache.org on 2009/12/01 20:13:01 UTC

svn commit: r885872 - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/de...

Author: curtisr7
Date: Tue Dec  1 19:13:01 2009
New Revision: 885872

URL: http://svn.apache.org/viewvc?rev=885872&view=rev
Log:
OPENJPA-1400: Fix PersistenceCapable.pcIsDetached() when using no statemanager and version is zero.

Added:
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachNoStateField.java   (with props)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityFieldAccess.java   (with props)
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityPropertyAccess.java   (with props)
Modified:
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java?rev=885872&r1=885871&r2=885872&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java Tue Dec  1 19:13:01 2009
@@ -115,6 +115,8 @@
     // Each enhanced class will return the value of this field via
     // public int getEnhancementContractVersion()
     public static final int ENHANCER_VERSION = 2;
+    
+    boolean _addVersionInitFlag = true;
 
     public static final int ENHANCE_NONE = 0;
     public static final int ENHANCE_AWARE = 2 << 0;
@@ -136,6 +138,8 @@
     private static final String SUPER = PRE + "PCSuperclass";
     private static final Class OIDFSTYPE = FieldSupplier.class;
     private static final Class OIDFCTYPE = FieldConsumer.class;
+    
+    private static final String VERSION_INIT_STR =  PRE + "VersionInit";
 
     private static final Localizer _loc = Localizer.forPackage
         (PCEnhancer.class);
@@ -430,6 +434,7 @@
      */
     public void setCreateSubclass(boolean subclass) {
         _subclass = subclass;
+        _addVersionInitFlag = false;
     }
 
     /**
@@ -1393,6 +1398,15 @@
                     code.checkcast().setType(fmds[i].getDeclaredType());
 
                 addSetManagedValueCode(code, fmds[i]);
+                if(_addVersionInitFlag){
+                    if(fmds[i].isVersion()){
+                        // If this case is setting the version field
+                        // pcVersionInit = true;
+                        loadManagedInstance(code, false);
+                        code.constant().setValue(1);
+                        putfield(code, null, VERSION_INIT_STR, boolean.class);
+                    }
+                }
                 code.vreturn();
             }
 
@@ -2750,7 +2764,12 @@
         _pc.declareField(PRE + "FieldTypes", Class[].class).setStatic(true);
         _pc.declareField(PRE + "FieldFlags", byte[].class).setStatic(true);
         _pc.declareField(SUPER, Class.class).setStatic(true);
-
+        if(_addVersionInitFlag && _meta.getVersionField()!=null){
+            // protected transient boolean pcVersionInit;
+            BCField field = _pc.declareField(VERSION_INIT_STR, boolean.class);
+            field.makeProtected();
+            field.setTransient(true);
+        }
         if (_meta.getPCSuperclass() == null || getCreateSubclass()) {
             BCField field = _pc.declareField(SM, SMTYPE);
             field.makeProtected();
@@ -3199,8 +3218,26 @@
             ifins = ifDefaultValue(code, version);
             code.getstatic().setField(Boolean.class, "TRUE", Boolean.class);
             code.areturn();
-            ifins.setTarget(code.getstatic().setField(Boolean.class, "FALSE",
-                Boolean.class));
+            if (!_addVersionInitFlag){
+                // else return false;
+                ifins.setTarget(code.getstatic().setField(Boolean.class, "FALSE", Boolean.class));
+            }else{
+                FieldMetaData versionInit = _meta.getDeclaredField(VERSION_INIT_STR);
+                
+                // noop
+                ifins.setTarget(code.nop());
+                // if (pcVersionInit != false)
+                // return true
+                // else return false;
+                loadManagedInstance(code, false);
+                getfield(code, null, versionInit.getName());
+                ifins = ifDefaultValue(code, versionInit);
+                code.getstatic().setField(Boolean.class, "TRUE", Boolean.class);
+                code.areturn();
+                ifins.setTarget(code.nop());
+                code.getstatic().setField(Boolean.class, "FALSE", Boolean.class);
+                
+            }
             code.areturn();
             return false;
         }
@@ -3662,6 +3699,13 @@
         loadManagedInstance(code, true, fmd);
         code.xload().setParam(firstParamOffset);
         addSetManagedValueCode(code, fmd);
+        if(fmd.isVersion()==true && _addVersionInitFlag){
+            // if we are setting the version, flip the versionInit flag to true
+            FieldMetaData v = _meta.addDeclaredField(VERSION_INIT_STR, boolean.class);
+            loadManagedInstance(code, true);
+            code.constant().setValue(1);
+            addSetManagedValueCode(code, v);   
+        }
         code.vreturn();
 
         // inst.pcStateManager.setting<fieldType>Field (inst,

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachNoStateField.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachNoStateField.java?rev=885872&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachNoStateField.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachNoStateField.java Tue Dec  1 19:13:01 2009
@@ -0,0 +1,88 @@
+/*
+ * 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.detachment;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.detachment.model.NoDetachedStateEntityFieldAccess;
+import org.apache.openjpa.persistence.detachment.model.NoDetachedStateEntityPropertyAccess;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestDetachNoStateField extends SingleEMFTestCase {
+
+    @Override
+    protected void setUp(Object... props) {
+        super.setUp(CLEAR_TABLES, "openjpa.DetachState", "loaded(DetachedStateField=false)",
+            NoDetachedStateEntityPropertyAccess.class, NoDetachedStateEntityFieldAccess.class);
+        loadDB();
+    }
+
+    /**
+     * This testcase was added for OPENJPA-1400.
+     */
+    public void testIsDetchedNoStateManagerZeroVersionField() {
+        OpenJPAEntityManagerSPI em = emf.createEntityManager();
+        NoDetachedStateEntityPropertyAccess property = em.find(NoDetachedStateEntityPropertyAccess.class, 1);
+        NoDetachedStateEntityFieldAccess field = em.find(NoDetachedStateEntityFieldAccess.class, 1);
+        em.close();
+
+        PersistenceCapable pcProperty = (PersistenceCapable) property;
+        PersistenceCapable pcField = (PersistenceCapable) field;
+
+        assertTrue(pcProperty.pcIsDetached());
+        assertTrue(pcField.pcIsDetached());
+    }
+
+    /**
+     * This testcase was added for OPENJPA-1400.
+     */
+    public void testPersistRelationshipToDetchedEntityZeroVersion() {
+        OpenJPAEntityManagerSPI em = emf.createEntityManager();
+        NoDetachedStateEntityPropertyAccess property = em.find(NoDetachedStateEntityPropertyAccess.class, 1);
+        em.close();
+
+        // Make sure we don't hit any exceptions when persisting a relationship to a detached
+        // entity.
+        em = emf.createEntityManager();
+        em.getTransaction().begin();
+        NoDetachedStateEntityFieldAccess field = em.find(NoDetachedStateEntityFieldAccess.class, 1);
+        field.setRelationship(property);
+        em.getTransaction().commit();
+        em.close();
+
+        // Make sure that the relationship was persisted
+        em = emf.createEntityManager();
+        field = em.find(NoDetachedStateEntityFieldAccess.class, 1);
+        property = field.getRelationship();
+        assertNotNull(property);
+        assertEquals(1, property.getId());
+
+    }
+
+    void loadDB() {
+        OpenJPAEntityManagerSPI em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.createNativeQuery("INSERT INTO NoDetachedStateEntityPropertyAccess (ID,VERSION) VALUES (1,0)")
+            .executeUpdate();
+        em.createNativeQuery("INSERT INTO NoDetachedStateEntityFieldAccess (ID,VERSION) VALUES (1,0)")
+            .executeUpdate();
+        em.getTransaction().commit();
+        em.close();
+    }
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachNoStateField.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityFieldAccess.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityFieldAccess.java?rev=885872&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityFieldAccess.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityFieldAccess.java Tue Dec  1 19:13:01 2009
@@ -0,0 +1,57 @@
+/*
+ * 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.detachment.model;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Version;
+
+@Entity
+public class NoDetachedStateEntityFieldAccess {
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	int id;
+	
+	@Version
+	int version;
+	
+	@Basic
+	String string;
+	
+	@ManyToOne
+	NoDetachedStateEntityPropertyAccess relationship;
+	
+	public NoDetachedStateEntityFieldAccess(){
+		
+	}
+	
+	public void setString(String s){
+		string = s;
+	}
+	public void setRelationship(NoDetachedStateEntityPropertyAccess r){
+		relationship = r;
+	}
+	public NoDetachedStateEntityPropertyAccess getRelationship(){
+		return relationship;
+	}
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityFieldAccess.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityPropertyAccess.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityPropertyAccess.java?rev=885872&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityPropertyAccess.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityPropertyAccess.java Tue Dec  1 19:13:01 2009
@@ -0,0 +1,63 @@
+/*
+ * 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.detachment.model;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+@Entity
+public class NoDetachedStateEntityPropertyAccess {
+	int id;
+	int version;
+	String string;
+	public NoDetachedStateEntityPropertyAccess(){
+		
+	}
+	@Id
+	@GeneratedValue(strategy=GenerationType.AUTO)
+	public int getId() {
+		return id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+	@Version
+	public int getVersion() {
+		return version;
+	}
+
+	public void setVersion(int version) {
+		this.version = version;
+	}
+	@Basic
+	public String getString() {
+		return string;
+	}
+
+	public void setString(String string) {
+		this.string = string;
+	}
+	
+	
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/NoDetachedStateEntityPropertyAccess.java
------------------------------------------------------------------------------
    svn:eol-style = native