Author: jgrassel Date: Wed Oct 16 17:43:21 2013 New Revision: 1532827 URL: http://svn.apache.org/r1532827 Log: OPENJPA-2438: EmbedFieldStrategy.containsEmbeddedResult() optimization fails under certain native sql query conditions
Added: openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EChild.java (with props) openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EGeneric.java (with props) openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EParent.java (with props) openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddedWithQuery.java (with props) Modified: openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java Modified: openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java?rev=1532827&r1=1532826&r2=1532827&view=diff ============================================================================== --- openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java (original) +++ openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java Wed Oct 16 17:43:21 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.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EChild.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EChild.java?rev=1532827&view=auto ============================================================================== --- openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EChild.java (added) +++ openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EChild.java Wed Oct 16 17:43:21 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.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EChild.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EGeneric.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EGeneric.java?rev=1532827&view=auto ============================================================================== --- openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EGeneric.java (added) +++ openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EGeneric.java Wed Oct 16 17:43:21 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.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EGeneric.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EParent.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EParent.java?rev=1532827&view=auto ============================================================================== --- openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EParent.java (added) +++ openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EParent.java Wed Oct 16 17:43:21 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.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/EParent.java ------------------------------------------------------------------------------ svn:eol-style = native Added: openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddedWithQuery.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddedWithQuery.java?rev=1532827&view=auto ============================================================================== --- openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddedWithQuery.java (added) +++ openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddedWithQuery.java Wed Oct 16 17:43:21 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.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddedWithQuery.java ------------------------------------------------------------------------------ svn:eol-style = native