| /* |
| * 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.mapping; |
| |
| import java.util.List; |
| import javax.persistence.EntityManager; |
| import javax.persistence.Query; |
| |
| import org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.*; |
| import org.apache.openjpa.persistence.common.utils.*; |
| import junit.framework.*; |
| |
| |
| public class TestCompositeIdTraversalInSQLMapping extends AbstractTestCase |
| { |
| |
| |
| public TestCompositeIdTraversalInSQLMapping(String name) |
| { |
| super(name, "jdbccactusapp"); |
| } |
| |
| |
| public void setUp() |
| { |
| deleteAll(OwnerOfEntityWithCompositeId.class); |
| deleteAll(EntityWithCompositeId.class); |
| } |
| private void persist(Integer uniqueId, String uniqueName, String relName) |
| { |
| OwnerOfEntityWithCompositeId owner = new OwnerOfEntityWithCompositeId(); |
| EntityWithCompositeId relative = new EntityWithCompositeId(); |
| owner.setName(uniqueName); |
| relative.setId(uniqueId); |
| relative.setName(relName); |
| relative.setValue("foo"); |
| owner.setRelation(relative); |
| |
| EntityManager em = currentEntityManager(); |
| startTx(em); |
| em.persist(owner); |
| endTx(em); |
| endEm(em); |
| } |
| public void testTraversalWhenSQLSelectsBothEndOfTheRelation () |
| { |
| EntityManager em = currentEntityManager(); |
| Integer uid = new Integer((int) (System.currentTimeMillis()%100000)); |
| String uName = "P"+uid; |
| String rName = "R"+uName; |
| |
| persist(uid, uName, rName); |
| |
| String sql = "SELECT a.NAME as OWNER_NAME, a.RELATION_ID as REL_ID," + |
| "a.RELATION_NAME as REL_NAME, b.ID as C_ID," + |
| "b.NAME as C_NAME, b.VALUE as C_VALUE " + |
| "FROM OWNER_OF_COMPOSITE_ID a, COMPOSITE_ID b " + |
| "WHERE a.RELATION_ID=b.ID AND a.RELATION_NAME=b.NAME " + |
| "AND a.NAME='" + uName + "'"; |
| |
| Query query = em.createNativeQuery(sql, |
| "SQLSelectsBothEndOfTheRelation"); |
| |
| List result = query.getResultList(); |
| |
| assertEquals(1,result.size()); |
| Object object = result.get(0); |
| assertEquals(Object[].class, object.getClass()); |
| Object[] array = (Object[])object; |
| assertEquals(2,array.length); |
| assertEquals(OwnerOfEntityWithCompositeId.class,array[0].getClass()); |
| assertEquals(EntityWithCompositeId.class,array[1].getClass()); |
| |
| OwnerOfEntityWithCompositeId owner = (OwnerOfEntityWithCompositeId) |
| array[0]; |
| |
| EntityWithCompositeId relative = (EntityWithCompositeId)array[1]; |
| |
| assertEquals(uName, owner.getName()); |
| assertEquals(owner.getRelation(), relative); |
| assertEquals(relative.getId(),uid); |
| assertEquals(relative.getName(), rName); |
| assertEquals("foo", relative.getValue()); |
| endEm(em); |
| } |
| |
| public void testTraversalWhenSQLSelectsOnlyOneEndOfTheRelation () |
| { |
| EntityManager em = currentEntityManager(); |
| Integer uid = new Integer((int) (System.currentTimeMillis()%100000)); |
| String uName = "P"+uid; |
| String rName = "R"+uName; |
| |
| persist (uid, uName, rName); |
| String sql = "SELECT a.NAME as OWNER_NAME, a.RELATION_ID as REL_ID," + |
| "a.RELATION_NAME as REL_NAME "+ |
| "FROM OWNER_OF_COMPOSITE_ID a " + |
| "WHERE a.NAME='" + uName + "'"; |
| |
| Query query = em.createNativeQuery(sql, |
| "SQLSelectsOnlyOneEndOfTheRelation"); |
| |
| List result = query.getResultList(); |
| |
| assertEquals(1,result.size()); |
| Object object = result.get(0); |
| assertEquals(OwnerOfEntityWithCompositeId.class,object.getClass()); |
| |
| OwnerOfEntityWithCompositeId owner = (OwnerOfEntityWithCompositeId) |
| object; |
| |
| EntityWithCompositeId relative = owner.getRelation(); |
| |
| assertEquals(uName, owner.getName()); |
| assertEquals(relative.getId(),uid); |
| assertEquals(relative.getName(), rName); |
| assertEquals("foo", relative.getValue()); |
| endEm(em); |
| } |
| public void testTraversalWhenSQLSelectsUnrelatedInstances () |
| { |
| EntityManager em = currentEntityManager(); |
| Integer uid1 = new Integer((int) (System.currentTimeMillis()%100000)); |
| Integer uid2 = new Integer(uid1.intValue()+1); |
| String uName1 = "P"+uid1; |
| String rName1 = "R"+uName1; |
| String uName2 = "P"+uid2; |
| String rName2 = "R"+uName2; |
| |
| persist(uid1, uName1, rName1); |
| persist(uid2, uName2, rName2); |
| |
| String sql = "SELECT a.NAME as OWNER_NAME, a.RELATION_ID AS REL_ID," + |
| "a.RELATION_NAME AS REL_NAME, " + |
| "b.ID AS C_ID, b.NAME AS C_NAME, b.VALUE AS C_VALUE "+ |
| "FROM OWNER_OF_COMPOSITE_ID a, COMPOSITE_ID b " + |
| "WHERE b.NAME='"+ rName2 +"' " + |
| "AND a.NAME='" + uName1 + "'"; |
| |
| Query query = em.createNativeQuery(sql, |
| "SQLSelectsUnrelatedInstances"); |
| |
| List result = query.getResultList(); |
| |
| assertEquals(1,result.size()); |
| Object object = result.get(0); |
| assertEquals(Object[].class, object.getClass()); |
| Object[] array = (Object[])object; |
| assertEquals(2,array.length); |
| assertEquals(OwnerOfEntityWithCompositeId.class,array[0].getClass()); |
| assertEquals(EntityWithCompositeId.class,array[1].getClass()); |
| |
| OwnerOfEntityWithCompositeId owner1 = (OwnerOfEntityWithCompositeId) |
| array[0]; |
| EntityWithCompositeId relative1 = owner1.getRelation(); |
| |
| EntityWithCompositeId relative2 = (EntityWithCompositeId)array[1]; |
| |
| assertEquals(uName1, owner1.getName()); |
| assertEquals(uid1, relative1.getId()); |
| assertEquals(rName1, relative1.getName()); |
| assertEquals(uid2, relative2.getId()); |
| assertEquals(rName2, relative2.getName()); |
| endEm(em); |
| } |
| |
| public void testRecursiveTraversal () |
| { |
| Integer rootId = new Integer((int)(System.currentTimeMillis()%100000)); |
| |
| int depth = 3; |
| persistChainedRelative(rootId, depth); |
| |
| String sql = createSelfJoinSQL("RECURSIVE_ENTITY", |
| depth,rootId); |
| |
| EntityManager em = currentEntityManager(); |
| Query query = em.createNativeQuery(sql, "SQLSelectsChainedRelation"); |
| |
| List result = query.getResultList(); |
| |
| assertEquals(1, result.size()); |
| assertEquals(RecursiveEntityWithCompositeId.class, |
| result.get(0).getClass()); |
| |
| RecursiveEntityWithCompositeId root = (RecursiveEntityWithCompositeId) |
| result.get(0); |
| assertEquals(rootId,root.getId()); |
| assertEquals("P"+rootId,root.getName()); |
| for (int i=1; i<depth;i++){ |
| RecursiveEntityWithCompositeId relative = root.getRelation(); |
| Integer expecetedId = root.getId()+1; |
| assertEquals (expecetedId,relative.getId()); |
| assertEquals ("P"+expecetedId, relative.getName()); |
| root = relative; |
| } |
| |
| } |
| |
| void persistChainedRelative(Integer rootId, int depth) |
| { |
| RecursiveEntityWithCompositeId root = |
| new RecursiveEntityWithCompositeId(); |
| root.setId(rootId); |
| root.setName("P"+rootId); |
| RecursiveEntityWithCompositeId head = root; |
| for (int i=1; i<=depth; i++) |
| { |
| RecursiveEntityWithCompositeId relation = |
| new RecursiveEntityWithCompositeId(); |
| relation.setId(rootId+i); |
| relation.setName("P"+(rootId+i)); |
| head.setRelation(relation); |
| head = relation; |
| } |
| EntityManager em = currentEntityManager(); |
| startTx(em); |
| em.persist(root); |
| endTx(em); |
| endEm(em); |
| } |
| |
| String createSelfJoinSQL(String table, int depth, int id) |
| { |
| |
| StringBuffer sql = new StringBuffer("SELECT "); |
| for (int i=0; i<depth; i++) |
| sql.append("t"+i+".ID AS T"+i+"_ID, ") |
| .append("t"+i+".NAME AS T"+i+"_NAME, ") |
| .append("t"+i+".RELATION_ID AS T"+i+"_REL_ID, ") |
| .append("t"+i+".RELATION_NAME AS T"+i+"_REL_NAME") |
| .append((i==(depth-1))?" " : ", "); |
| |
| sql.append(" FROM "); |
| for (int i=0; i<depth; i++) |
| sql.append(table + " t"+i) |
| .append((i==(depth-1))?" " : ", "); |
| |
| sql.append(" WHERE "); |
| for (int i=0; i<(depth-1); i++) |
| sql.append("t"+i+".RELATION_ID=t"+(i+1)+".ID AND ") |
| .append("t"+i+".RELATION_NAME=t"+(i+1)+".NAME AND " ); |
| |
| sql.append("t0.ID="+id); |
| |
| return sql.toString(); |
| } |
| } |