Author: hthomann Date: Thu Oct 17 19:14:40 2013 New Revision: 1533218 URL: http://svn.apache.org/r1533218 Log: OPENJPA-2343: Version field returns null when explicity projected from a JOIN in SELECT clause - based fix off of patch provided by Howard Kelsey.
Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/Author.java openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/Document.java openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/TestJoinVersionField.java Modified: openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Version.java openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/VersionStrategy.java openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractVersionStrategy.java openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ColumnVersionStrategy.java Modified: openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java?rev=1533218&r1=1533217&r2=1533218&view=diff ============================================================================== --- openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java (original) +++ openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java Thu Oct 17 19:14:40 2013 @@ -1006,7 +1006,7 @@ public class FieldMapping // OPENJPA-662: Version fields have NoneFieldStrategy -- hence they // need special treatment if (isVersion()) { - return getDefiningMapping().getVersion().load(null, store, res); + return getDefiningMapping().getVersion().load(null, store, res, joins); } return assertStrategy().loadProjection(store, fetch, res, joins); } Modified: openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Version.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Version.java?rev=1533218&r1=1533217&r2=1533218&view=diff ============================================================================== --- openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Version.java (original) +++ openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/Version.java Thu Oct 17 19:14:40 2013 @@ -26,6 +26,7 @@ import org.apache.openjpa.jdbc.schema.Co import org.apache.openjpa.jdbc.schema.ColumnIO; import org.apache.openjpa.jdbc.schema.Index; import org.apache.openjpa.jdbc.schema.Schemas; +import org.apache.openjpa.jdbc.sql.Joins; import org.apache.openjpa.jdbc.sql.Result; import org.apache.openjpa.jdbc.sql.RowManager; import org.apache.openjpa.jdbc.sql.Select; @@ -343,6 +344,11 @@ public class Version return assertStrategy().load(sm, store, res); } + public Object load(OpenJPAStateManager sm, JDBCStore store, Result res, Joins joins) + throws SQLException { + return assertStrategy().load(sm, store, res, joins); + } + public void afterLoad(OpenJPAStateManager sm, JDBCStore store) { assertStrategy().afterLoad(sm, store); } Modified: openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/VersionStrategy.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/VersionStrategy.java?rev=1533218&r1=1533217&r2=1533218&view=diff ============================================================================== --- openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/VersionStrategy.java (original) +++ openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/VersionStrategy.java Thu Oct 17 19:14:40 2013 @@ -23,6 +23,7 @@ import java.util.Map; import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.schema.Column; +import org.apache.openjpa.jdbc.sql.Joins; import org.apache.openjpa.jdbc.sql.Result; import org.apache.openjpa.jdbc.sql.Select; import org.apache.openjpa.kernel.OpenJPAStateManager; @@ -55,6 +56,12 @@ public interface VersionStrategy */ public Object load(OpenJPAStateManager sm, JDBCStore store, Result res) throws SQLException; + + /** + * Load data. + */ + public Object load(OpenJPAStateManager sm, JDBCStore store, Result res, Joins joins) + throws SQLException; /** * This method is called after data is loaded into the instance, in Modified: openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractVersionStrategy.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractVersionStrategy.java?rev=1533218&r1=1533217&r2=1533218&view=diff ============================================================================== --- openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractVersionStrategy.java (original) +++ openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractVersionStrategy.java Thu Oct 17 19:14:40 2013 @@ -19,13 +19,14 @@ package org.apache.openjpa.jdbc.meta.strats; import java.sql.SQLException; -import java.util.Map; import java.util.Collections; +import java.util.Map; import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.meta.ClassMapping; import org.apache.openjpa.jdbc.meta.Version; import org.apache.openjpa.jdbc.meta.VersionStrategy; +import org.apache.openjpa.jdbc.sql.Joins; import org.apache.openjpa.jdbc.sql.Result; import org.apache.openjpa.jdbc.sql.Select; import org.apache.openjpa.kernel.OpenJPAStateManager; @@ -58,6 +59,11 @@ public abstract class AbstractVersionStr return null; } + public Object load(OpenJPAStateManager sm, JDBCStore store, Result res, Joins joins) + throws SQLException { + return null; + } + public void afterLoad(OpenJPAStateManager sm, JDBCStore store) { } Modified: openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ColumnVersionStrategy.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ColumnVersionStrategy.java?rev=1533218&r1=1533217&r2=1533218&view=diff ============================================================================== --- openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ColumnVersionStrategy.java (original) +++ openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ColumnVersionStrategy.java Thu Oct 17 19:14:40 2013 @@ -28,11 +28,13 @@ import org.apache.openjpa.jdbc.kernel.JD import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.meta.ClassMapping; import org.apache.openjpa.jdbc.meta.VersionMappingInfo; +import org.apache.openjpa.jdbc.meta.strats.AbstractVersionStrategy; import org.apache.openjpa.jdbc.schema.Column; import org.apache.openjpa.jdbc.schema.ColumnIO; import org.apache.openjpa.jdbc.schema.ForeignKey; import org.apache.openjpa.jdbc.schema.Index; import org.apache.openjpa.jdbc.sql.DBDictionary; +import org.apache.openjpa.jdbc.sql.Joins; import org.apache.openjpa.jdbc.sql.Result; import org.apache.openjpa.jdbc.sql.Row; import org.apache.openjpa.jdbc.sql.RowManager; @@ -257,16 +259,22 @@ public abstract class ColumnVersionStrat sel.select(vers.getColumns()); return true; } + + public Object load(OpenJPAStateManager sm, JDBCStore store, Result res) + throws SQLException { + return this.load(sm, store, res, null); + } - public Object load(OpenJPAStateManager sm, JDBCStore store, Result res) + public Object load(OpenJPAStateManager sm, JDBCStore store, Result res, Joins joins) throws SQLException { // typically if one version column is in the result, they all are, so // optimize by checking for the first one before doing any real work Column[] cols = vers.getColumns(); - if (!res.contains(cols[0])) + if (!res.contains(cols[0], joins)) { return null; + } - Object version = populateFromResult(res); + Object version = populateFromResult(res, joins); // OPENJPA-662 Allow a null StateManager because this method may just be // invoked to get the result of projection query @@ -295,7 +303,7 @@ public abstract class ColumnVersionStrat return false; Object memVersion = sm.getVersion(); - Object dbVersion = populateFromResult(res); + Object dbVersion = populateFromResult(res, null); boolean refresh = compare(memVersion, dbVersion) < 0; if (updateVersion) @@ -326,14 +334,14 @@ public abstract class ColumnVersionStrat * @return a single Object or an array depending on whether using a single * or multiple columns being used for representation. */ - Object populateFromResult(Result res) throws SQLException { + Object populateFromResult(Result res, Joins joins) throws SQLException { if (res == null) return null; Column[] cols = vers.getColumns(); Object[] values = new Object[cols.length]; for (int i = 0; i < cols.length; i++) { - values[i] = res.getObject(cols[i], -1, null); + values[i] = res.getObject(cols[i], null, joins); } return (cols.length == 1) ? values[0] : values; } Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/Author.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/Author.java?rev=1533218&view=auto ============================================================================== --- openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/Author.java (added) +++ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/Author.java Thu Oct 17 19:14:40 2013 @@ -0,0 +1,40 @@ +/* + * 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.jpql.version; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Version; + +@Entity +public class Author { + + @Id + private int id; + + @Version + private int version; + + public int getId() { return id; } + public void setId(int id) { this.id = id; } + + public int getVersion() { return version; } + public void setVersion(int version) { this.version = version; } +} + Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/Document.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/Document.java?rev=1533218&view=auto ============================================================================== --- openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/Document.java (added) +++ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/Document.java Thu Oct 17 19:14:40 2013 @@ -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.jpql.version; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; + +@Entity +public class Document { + + @Id + private int id; + + @ManyToOne + private Author author; + + public int getId() { return id; } + public void setId(int id) { this.id = id; } + public Author getAuthor() { return author; } + public void setAuthor(Author author) { this.author = author; } +} Added: openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/TestJoinVersionField.java URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/TestJoinVersionField.java?rev=1533218&view=auto ============================================================================== --- openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/TestJoinVersionField.java (added) +++ openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/version/TestJoinVersionField.java Thu Oct 17 19:14:40 2013 @@ -0,0 +1,85 @@ +/* + * 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.jpql.version; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; +import javax.persistence.TypedQuery; + +import org.apache.openjpa.persistence.test.SingleEMFTestCase; + +/** + * Verifies that the version field is returned when part of a join statement. + * See OPENJPA-2343. + */ +public class TestJoinVersionField extends SingleEMFTestCase { + + public void setUp(){ + setUp(CLEAR_TABLES, Author.class,Document.class); + createTestData(); + } + + public void testGetDocuments(){ + EntityManager em = emf.createEntityManager(); + String str = "SELECT doc FROM Document doc JOIN doc.author auth"; + TypedQuery<Document> query = em.createQuery(str, Document.class); + List<Document> documentList = query.getResultList(); + + for (Document doc : documentList) { + assertEquals("Author version field should have a value of 1.", + 1, doc.getAuthor().getVersion()); + } + + em.close(); + } + + /** + * Prior to OPENJPA-2343, the version field in the Author entity is returned + * as null. + */ + public void testGetDocumentsByExplicitAttributeSelection(){ + EntityManager em = emf.createEntityManager(); + String str = "SELECT doc.id, auth.id, auth.version FROM Document doc JOIN doc.author auth"; + Query query = em.createQuery(str); + List<Object[]> objectList = query.getResultList(); + + for (Object[] objects : objectList) { + assertEquals("Author version field should have a value of 1.",1,objects[2]); + } + } + + public void createTestData() { + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + + Author author = new Author(); + author.setId(10); + em.persist(author); + + Document document = new Document(); + document.setId(2); + document.setAuthor(author); + em.persist(document); + + em.getTransaction().commit(); + em.close(); + } +}