You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by jg...@apache.org on 2013/10/15 21:52:54 UTC

svn commit: r1532504 - in /openjpa/branches/2.2.1.x: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/

Author: jgrassel
Date: Tue Oct 15 19:52:54 2013
New Revision: 1532504

URL: http://svn.apache.org/r1532504
Log:
OPENJPA-2438: EmbedFieldStrategy.containsEmbeddedResult() optimization fails under certain native sql query conditions

Added:
    openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EChild.java   (with props)
    openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EGeneric.java   (with props)
    openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EParent.java   (with props)
    openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddedWithQuery.java   (with props)
Modified:
    openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java

Modified: openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java?rev=1532504&r1=1532503&r2=1532504&view=diff
==============================================================================
--- openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java (original)
+++ openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java Tue Oct 15 19:52:54 2013
@@ -445,13 +445,25 @@ public class EmbedFieldStrategy
      */
     private boolean containsEmbeddedResult(FetchConfiguration fetch, Result res) {
         FieldMapping[] fields = field.getEmbeddedMapping().getFieldMappings();
+        boolean containsUnloadedEagerField = false;
+        
         for (int i = 0; i < fields.length; i++) {
-            boolean load = (fetch.requiresFetch(fields[i]) == FetchConfiguration.FETCH_LOAD);
-            if (load) {
-                // check the first eager fetch field
-                return checkResult(fields[i],res);
+            boolean inResultSet = checkResult(fields[i],res);                
+            if (inResultSet) {
+                // At least one of the embeddable's field is in the ResultSet.
+                return true;
+            }
+            
+            if (fetch.requiresFetch(fields[i]) == FetchConfiguration.FETCH_LOAD) {
+                containsUnloadedEagerField = true;
             }
         }
+        
+        // A field expected to be loaded eagerly was missing from the ResultSet.
+        if (containsUnloadedEagerField == true) {
+            return false;
+        }
+        
         // if all fields are lazy and in the default fetch group, populate the embeddable 
         // so its attributes can be loaded when accessed.
         return fetch.hasFetchGroup(FetchGroup.NAME_DEFAULT);

Added: openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EChild.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EChild.java?rev=1532504&view=auto
==============================================================================
--- openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EChild.java (added)
+++ openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EChild.java Tue Oct 15 19:52:54 2013
@@ -0,0 +1,46 @@
+/*
+ * 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.embed;
+
+import javax.persistence.Embeddable;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+@Embeddable
+public class EChild {
+    private Long idChild = null;
+    private String missing = null;
+
+    @Id
+    public Long getIdChild() {
+        return this.idChild;
+    }
+    public void setIdChild(Long idChild) {
+        this.idChild = idChild;
+    }
+
+    public String getMissing() {
+        return this.missing;
+    }
+    public void setMissing(String missing) {
+        this.missing = missing;
+    }
+}

Propchange: openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EChild.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EGeneric.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EGeneric.java?rev=1532504&view=auto
==============================================================================
--- openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EGeneric.java (added)
+++ openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EGeneric.java Tue Oct 15 19:52:54 2013
@@ -0,0 +1,68 @@
+/*
+ * 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.embed;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="EGENERIC")
+public class EGeneric {
+    @Id
+    @Column(name="id")
+    private Integer id = null;
+    
+    @Basic @Column(name="longVal")
+    private Long longVal = null;
+    
+    @Basic @Column(name="strVal")
+    private String strVal = null;
+    
+    public EGeneric() {
+        
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Long getLongVal() {
+        return longVal;
+    }
+
+    public void setLongVal(Long longVal) {
+        this.longVal = longVal;
+    }
+
+    public String getStrVal() {
+        return strVal;
+    }
+
+    public void setStrVal(String strVal) {
+        this.strVal = strVal;
+    }
+}

Propchange: openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EGeneric.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EParent.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EParent.java?rev=1532504&view=auto
==============================================================================
--- openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EParent.java (added)
+++ openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EParent.java Tue Oct 15 19:52:54 2013
@@ -0,0 +1,48 @@
+/*
+ * 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.embed;
+
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="EMBED_EPARENT")
+public class EParent {
+    private Integer idParent = null;
+    private EChild childTo = null;
+    
+    @Id
+    public Integer getIdParent() {
+        return this.idParent;
+    }
+    public void setIdParent(Integer idParent) {
+        this.idParent = idParent;
+    }
+
+    @Embedded
+    public EChild getChildTo() {
+        return this.childTo;
+    }
+    public void setChildTo(EChild child) {
+        this.childTo = child;
+    }
+}

Propchange: openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EParent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddedWithQuery.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddedWithQuery.java?rev=1532504&view=auto
==============================================================================
--- openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddedWithQuery.java (added)
+++ openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddedWithQuery.java Tue Oct 15 19:52:54 2013
@@ -0,0 +1,125 @@
+/*
+ * 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.embed;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestEmbeddedWithQuery extends SingleEMFTestCase {
+    public void setUp() {
+        setUp(EParent.class, EChild.class, EGeneric.class,
+            "openjpa.MaxFetchDepth", "1",
+            "openjpa.jdbc.EagerFetchMode", "none",
+            "openjpa.jdbc.SubclassFetchMode", "none",
+            CLEAR_TABLES);
+        populate();
+    }
+    
+    public void testFullEmbeddableLoadByJPQLQuery() {
+        EntityManager em = emf.createEntityManager();
+        
+        try {
+            String queryStr = 
+                    "SELECT id AS idparent, longVal AS idchild, CAST(NULL AS CHAR)  as missing FROM EGENERIC";
+                    //"SELECT 1 as idparent, 2 as idchild,CAST(NULL AS CHAR) as missing " 
+                    // FROM sysibm.sysdummy1";
+            Query q1 = em.createNativeQuery(queryStr, EParent.class);
+            
+            List resultList = q1.getResultList(); 
+            assertNotNull(resultList);
+            
+            List <EParent> pList = new ArrayList<EParent>();
+            pList.addAll(resultList);
+            em.clear();                      
+            assertNotEquals(0, pList.size());
+            
+            EParent pFind = pList.get(0);
+            
+            assertNotNull(pFind);
+            assertEquals(pFind.getIdParent(), new Integer(1));
+            assertNotNull(pFind.getChildTo());
+            assertEquals(pFind.getChildTo().getIdChild(), new Long(10));
+        } finally {
+            if (em.getTransaction().isActive()) {
+                em.getTransaction().rollback();
+            }
+            
+            em.close();
+        }
+    }
+    
+    public void testPartialEmbeddableLoadByJPQLQuery() {
+        EntityManager em = emf.createEntityManager();
+        
+        try {
+            String queryStr = "SELECT id AS idparent, longVal AS idchild FROM EGENERIC";
+            Query q1 = em.createNativeQuery(queryStr, EParent.class);
+            
+            List resultList = q1.getResultList(); 
+            assertNotNull(resultList);
+            
+            List <EParent> pList = new ArrayList<EParent>();
+            pList.addAll(resultList);
+            em.clear();                      
+            assertNotEquals(0, pList.size());
+            
+            EParent pFind = pList.get(0);
+            
+            assertNotNull(pFind);
+            assertEquals(pFind.getIdParent(), new Integer(1));
+            assertNotNull(pFind.getChildTo());
+            assertEquals(pFind.getChildTo().getIdChild(), new Long(10));
+        } finally {
+            if (em.getTransaction().isActive()) {
+                em.getTransaction().rollback();
+            }
+            
+            if (em.isOpen()) {
+                em.close();
+            }
+        }
+    }
+    
+    private void populate() {
+        EntityManager em = emf.createEntityManager();
+        
+        try {
+            EGeneric generic = new EGeneric();
+            generic.setId(new Integer(1));
+            generic.setLongVal(new Long(10));
+            generic.setStrVal("Nope");
+            
+            em.getTransaction().begin();
+            em.persist(generic);
+            em.getTransaction().commit();       
+        } finally {
+            if (em.getTransaction().isActive()) {
+                em.getTransaction().rollback();
+            }
+            
+            em.close();
+        }
+    }
+}

Propchange: openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddedWithQuery.java
------------------------------------------------------------------------------
    svn:eol-style = native