diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnidirectionalOneToOneOwned.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnidirectionalOneToOneOwned.java new file mode 100644 index 000000000..afd66df2b --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnidirectionalOneToOneOwned.java @@ -0,0 +1,61 @@ +/* + * 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.jdbc.common.apps; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Version; + +/** + * Entity which is traget of a unidirectional one-to-one relation. + * + * Used in + * @see org.apache.openjpa.persistence.query.TestProjectionQueryWithIdenticalResult + * + * @author Pinaki Poddar + * + */ +@Entity +public class UnidirectionalOneToOneOwned { + @Id + @GeneratedValue + private long id; + + private String marker; + + @Version + private int version; + + public String getMarker() { + return marker; + } + + public void setMarker(String marker) { + this.marker = marker; + } + + public long getId() { + return id; + } + + public int getVersion() { + return version; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnidirectionalOneToOneOwner.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnidirectionalOneToOneOwner.java new file mode 100644 index 000000000..bb45cdab4 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/common/apps/UnidirectionalOneToOneOwner.java @@ -0,0 +1,74 @@ +/* + * 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.jdbc.common.apps; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Version; + +/** + * Persistent entity with unidirectional one-to-one relation. + * + * Used in + * @see org.apache.openjpa.persistence.query.TestProjectionQueryWithIdenticalResult + * + * @author Pinaki Poddar + * + */ +@Entity +public class UnidirectionalOneToOneOwner { + @Id + @GeneratedValue + private long id; + + private String marker; + + @Version + private int version; + + @OneToOne(cascade=CascadeType.ALL) + private UnidirectionalOneToOneOwned owned; + + public String getMarker() { + return marker; + } + + public void setMarker(String marker) { + this.marker = marker; + } + + public UnidirectionalOneToOneOwned getOwned() { + return owned; + } + + public void setOwned(UnidirectionalOneToOneOwned owned) { + this.owned = owned; + } + + public long getId() { + return id; + } + + public int getVersion() { + return version; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestProjectionQueryWithIdenticalResult.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestProjectionQueryWithIdenticalResult.java new file mode 100644 index 000000000..c305aeeb4 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestProjectionQueryWithIdenticalResult.java @@ -0,0 +1,109 @@ +/* + * 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.query; + +import java.util.List; + +import javax.persistence.EntityManager; + +import org.apache.openjpa.persistence.jdbc.common.apps.UnidirectionalOneToOneOwned; +import org.apache.openjpa.persistence.jdbc.common.apps.UnidirectionalOneToOneOwner; +import org.apache.openjpa.persistence.test.SingleEMFTestCase; + + +/** + * The query uses projection and result contains the same instance once as + * a direct projection and again as a fetch group of the other projection. + * Does the query return two separate instances or one identical instance? + * + * Originally reported as two different failures: + * OPENJPA-209 + * OPENJPA-210 + * + * @author Pinaki Poddar + */ +public class TestProjectionQueryWithIdenticalResult extends SingleEMFTestCase { + private static boolean USE_TXN = true; + public void setUp() { + setUp(CLEAR_TABLES, + UnidirectionalOneToOneOwned.class, + UnidirectionalOneToOneOwner.class); + + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + UnidirectionalOneToOneOwner owner = new UnidirectionalOneToOneOwner(); + owner.setMarker("Owner"); + UnidirectionalOneToOneOwned owned = new UnidirectionalOneToOneOwned(); + owned.setMarker("Owned"); + owner.setOwned(owned); + em.persist(owner); + em.getTransaction().commit(); + em.close(); + } + + public void testDuplicateResultInProjection1() { + String jpql = "SELECT p.owned, p FROM UnidirectionalOneToOneOwner p"; + List result = executeQuery(jpql, USE_TXN); + for (Object[] row : result) { + assertTrue(row[0] instanceof UnidirectionalOneToOneOwned); + assertTrue(row[1] instanceof UnidirectionalOneToOneOwner); + assertTrue(((UnidirectionalOneToOneOwner)row[1]).getOwned() == row[0]); + } + } + + public void testDuplicateResultInProjection2() { + String jpql = "SELECT p, p.owned FROM UnidirectionalOneToOneOwner p"; + List result = executeQuery(jpql, USE_TXN); + for (Object[] row : result) { + assertTrue(row[1] instanceof UnidirectionalOneToOneOwned); + assertTrue(row[0] instanceof UnidirectionalOneToOneOwner); + assertTrue(((UnidirectionalOneToOneOwner)row[0]).getOwned() == row[1]); + } + } + + public void testDuplicateResultInProjection3() { + String jpql = "SELECT p, q FROM UnidirectionalOneToOneOwner p, " + + "UnidirectionalOneToOneOwned q WHERE p.owned = q"; + List result = executeQuery(jpql, USE_TXN); + for (Object[] row : result) { + assertTrue(row[0] instanceof UnidirectionalOneToOneOwner); + assertTrue(row[1] instanceof UnidirectionalOneToOneOwned); + assertTrue(((UnidirectionalOneToOneOwner)row[0]).getOwned() == row[1]); + } + } + + public void testDuplicateResultInProjection4() { + String jpql = "SELECT q, p FROM UnidirectionalOneToOneOwner p, " + + "UnidirectionalOneToOneOwned q WHERE p.owned = q"; + List result = executeQuery(jpql, USE_TXN); + for (Object[] row : result) { + assertTrue(row[0] instanceof UnidirectionalOneToOneOwned); + assertTrue(row[1] instanceof UnidirectionalOneToOneOwner); + assertTrue(((UnidirectionalOneToOneOwner)row[1]).getOwned() == row[0]); + } + } + + private List executeQuery(String jpql, boolean useTxn) { + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + List result = em.createQuery(jpql).getResultList(); + em.getTransaction().rollback(); + return result; + } +}