From c14838950cd361f54f9ca913c396df570e368b1e Mon Sep 17 00:00:00 2001 From: Fay Wang Date: Thu, 1 Oct 2009 23:18:56 +0000 Subject: [PATCH] OPENJPA-1330: support join table strategy for uni-directional many-to-one relation and uni-/bi-directional one-to-one relation. git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@820839 13f79535-47bb-0310-9956-ffa450edef68 --- .../openjpa/jdbc/meta/FieldMapping.java | 37 ++- .../openjpa/jdbc/meta/MappingRepository.java | 74 ++++-- .../meta/strats/RelationFieldStrategy.java | 2 +- .../persistence/compat/Bi_1To1_JT.java | 76 ++++++ .../persistence/compat/EntityC_B11JT.java | 68 +++++ .../persistence/compat/EntityC_U11JT.java | 56 +++++ .../compat/TestSpecCompatibilityOptions.java | 233 ++++++++++++++++-- .../persistence/compat/Uni_1To1_JT.java | 75 ++++++ .../persistence/compat/Uni_MTo1_JT.java | 75 ++++++ 9 files changed, 652 insertions(+), 44 deletions(-) create mode 100644 openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1To1_JT.java create mode 100644 openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B11JT.java create mode 100644 openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U11JT.java create mode 100644 openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1To1_JT.java create mode 100644 openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_MTo1_JT.java diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java index 22ccda2e8..a4d8f5eb1 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java @@ -84,6 +84,10 @@ public class FieldMapping private Boolean _bi_MTo1_JT = null; private Boolean _uni_1ToM_FK = null; + private Boolean _uni_MTo1_JT = null; + private Boolean _uni_1To1_JT = null; + private Boolean _bi_1To1_JT = null; + private FieldMapping _bi_1ToM_JT_Field = null; private FieldMapping _bi_MTo1_JT_Field = null; private ForeignKey _bi_1ToM_Join_FK = null; @@ -1258,6 +1262,30 @@ public class FieldMapping return _bi_MTo1_JT; } + public boolean isUni1ToMFK() { + if (_uni_1ToM_FK == null) + _uni_1ToM_FK = getMappingRepository().isUni1ToMFK(this); + return _uni_1ToM_FK; + } + + public boolean isUniMTo1JT() { + if (_uni_MTo1_JT == null) + _uni_MTo1_JT = getMappingRepository().isUniMTo1JT(this); + return _uni_MTo1_JT; + } + + public boolean isUni1To1JT() { + if (_uni_1To1_JT == null) + _uni_1To1_JT = getMappingRepository().isUni1To1JT(this); + return _uni_1To1_JT; + } + + public boolean isBi1To1JT() { + if (_bi_1To1_JT == null) + _bi_1To1_JT = getMappingRepository().isBi1To1JT(this); + return _bi_1To1_JT; + } + public FieldMapping getBi_1ToM_JTField() { if (_bi_1ToM_JT_Field == null) { _bi_1ToM_JT_Field = getMappingRepository().getBi_1ToM_JoinTableField(this); @@ -1290,12 +1318,6 @@ public class FieldMapping return _bi_1ToM_Elem_FK; } - public boolean isUni1ToMFK() { - if (_uni_1ToM_FK == null) - _uni_1ToM_FK = getMappingRepository().isUni1ToMFK(this); - return _uni_1ToM_FK; - } - public void setBi1MJoinTableInfo() { if (getAssociationType() == FieldMetaData.ONE_TO_MANY) { FieldMapping mapped = getBi_MTo1_JTField(); @@ -1310,4 +1332,7 @@ public class FieldMapping } } + public boolean isNonDefaultMappingUsingJoinTableStrategy() { + return isBi1To1JT() || isUni1To1JT() || isUniMTo1JT() || isBiMTo1JT(); + } } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java index b48ecc626..082238d9d 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java @@ -1016,19 +1016,46 @@ public class MappingRepository return getMetaDataFactory().getDefaults().isNonDefaultMappingAllowed(conf); } + public boolean isUniMTo1JT(FieldMapping field) { + if (isNonDefaultMappingAllowed() && + field.getAssociationType() == FieldMetaData.MANY_TO_ONE && + hasJoinTable(field) && + !isBidirectional(field)) { + field.getValueMapping().getValueInfo().setColumns(field.getElementMapping().getValueInfo().getColumns()); + return true; + } + return false; + } + + public boolean isUni1To1JT(FieldMapping field) { + if (isNonDefaultMappingAllowed() && + field.getAssociationType() == FieldMetaData.ONE_TO_ONE && + hasJoinTable(field) && + !isBidirectional(field)) { + field.getValueMapping().getValueInfo().setColumns(field.getElementMapping().getValueInfo().getColumns()); + return true; + } + return false; + } + + public boolean isBi1To1JT(FieldMapping field) { + if (isNonDefaultMappingAllowed() && + field.getAssociationType() == FieldMetaData.ONE_TO_ONE && + hasJoinTable(field) && + isBidirectional(field)) { + field.getValueMapping().getValueInfo().setColumns(field.getElementMapping().getValueInfo().getColumns()); + return true; + } + return false; + } + public boolean isUni1ToMFK(FieldMapping field) { - FieldMapping mapped = field.getMappedByMapping(); - if (isNonDefaultMappingAllowed()) { - if (field.getAssociationType() == FieldMetaData.ONE_TO_MANY ) { - if (mapped == null) { - if (hasJoinTable(field)) - return false; - else if (hasJoinColumn(field)) { - field.getElementMapping().getValueInfo().setColumns(field.getValueInfo().getColumns()); - return true; - } - } - } + if (isNonDefaultMappingAllowed() && + field.getAssociationType() == FieldMetaData.ONE_TO_MANY && + hasJoinColumn(field) && + !isBidirectional(field)) { + field.getElementMapping().getValueInfo().setColumns(field.getValueInfo().getColumns()); + return true; } return false; } @@ -1076,12 +1103,8 @@ public class MappingRepository if (field.getAssociationType() == FieldMetaData.MANY_TO_ONE) { if (!hasJoinTable(field)) return null; - ClassMapping inverse = field.getValueMapping().getTypeMapping(); - FieldMapping[] fmds = inverse.getFieldMappings(); - for (int i = 0; i < fmds.length; i++) { - if (field == fmds[i].getMappedByMapping()) - return field; - } + if (isBidirectional(field)) + return field; } else if (field.getAssociationType() == FieldMetaData.ONE_TO_MANY) { FieldMapping mappedBy = field.getMappedByMapping(); if (mappedBy != null && hasJoinTable(mappedBy)) @@ -1100,6 +1123,21 @@ public class MappingRepository boolean hasJoinTable = field.getMappingInfo().getTableName() != null ? true : false; return hasJoinTable; } + + public boolean isBidirectional(FieldMapping field) { + if (field.getMappedByMapping() != null) return true; + int assoType = field.getAssociationType(); + if (assoType == FieldMetaData.ONE_TO_ONE || + assoType == FieldMetaData.MANY_TO_ONE) { + ClassMapping inverse = field.getValueMapping().getTypeMapping(); + FieldMapping[] fmds = inverse.getFieldMappings(); + for (int i = 0; i < fmds.length; i++) { + if (field == fmds[i].getMappedByMapping()) + return true; + } + } + return false; + } /** * Check the given value against mapped strategies. diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java index 25903cb33..04de366d9 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java @@ -88,7 +88,7 @@ public class RelationFieldStrategy field.getKeyMapping().getValueInfo().assertNoSchemaComponents (field.getKey(), !adapt); - if (!field.isBiMTo1JT()) + if (!field.isNonDefaultMappingUsingJoinTableStrategy()) field.getElementMapping().getValueInfo().assertNoSchemaComponents (field.getElement(), !adapt); boolean criteria = field.getValueInfo().getUseClassCriteria(); diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1To1_JT.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1To1_JT.java new file mode 100644 index 000000000..e1d860303 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1To1_JT.java @@ -0,0 +1,76 @@ +/* + * 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.compat; + +import javax.persistence.*; + +@Entity +public class Bi_1To1_JT { + + @Id + @GeneratedValue + private long id; + + private String name; + + // A JoinTable annotation is specified on the owning side of the association + @OneToOne + @JoinTable( + name="Bi11JT_C", + joinColumns= + @JoinColumn(name="B_ID", referencedColumnName="ID"), + inverseJoinColumns= + @JoinColumn(name="C_ID", referencedColumnName="ID") + ) + private EntityC_B11JT entityC; + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public EntityC_B11JT getEntityC() { + return entityC; + } + + public void setEntityC(EntityC_B11JT entityC) { + this.entityC = entityC; + } + + public int hashCode() { + return name.hashCode() + (int)id; + } + + public boolean equals(Object o) { + if (!(o instanceof Bi_1To1_JT)) return false; + Bi_1To1_JT b = (Bi_1To1_JT)o; + if (!b.name.equals(name)) return false; + if (b.id != id) return false; + if (b.entityC == null && entityC == null) return true; + if (b.entityC.getId() != entityC.getId()) return false; + return true; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B11JT.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B11JT.java new file mode 100644 index 000000000..7422a6339 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B11JT.java @@ -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.compat; + +import javax.persistence.*; + +@Entity +public class EntityC_B11JT { + + @Id + @GeneratedValue + private long id; + + private String name; + + @OneToOne(mappedBy="entityC") + private Bi_1To1_JT bi11jt; + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setBi11jt(Bi_1To1_JT bi11jt) { + this.bi11jt = bi11jt; + } + + public Bi_1To1_JT getBi11jt() { + return bi11jt; + } + + public int hashCode() { + return name.hashCode() + (int)id; + } + + public boolean equals(Object o) { + if (!(o instanceof EntityC_B11JT)) return false; + EntityC_B11JT c = (EntityC_B11JT)o; + if (!c.name.equals(name)) return false; + if (c.id != id) return false; + if (c.bi11jt == null && bi11jt == null) return true; + if (!c.bi11jt.equals(bi11jt)) return false; + return true; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U11JT.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U11JT.java new file mode 100644 index 000000000..6c7bc8c81 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U11JT.java @@ -0,0 +1,56 @@ +/* + * 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.compat; + +import javax.persistence.*; + + +@Entity +public class EntityC_U11JT { + + @Id + @GeneratedValue + private long id; + + private String name; + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int hashCode() { + return name.hashCode() + (int)id; + } + + public boolean equals(Object o) { + if (!(o instanceof EntityC_U11JT)) return false; + EntityC_U11JT c = (EntityC_U11JT)o; + if (!c.name.equals(name)) return false; + if (c.id != id) return false; + return true; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestSpecCompatibilityOptions.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestSpecCompatibilityOptions.java index dcb03c475..5eb9ed642 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestSpecCompatibilityOptions.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestSpecCompatibilityOptions.java @@ -201,7 +201,7 @@ extends AbstractCachedEMFTestCase { public void crudUni1MFK(EntityManager em) { //create Uni_1ToM_FK u = new Uni_1ToM_FK(); - u.setName("uni1mfk"); + u.setName("u"); List cs = new ArrayList(); EntityC_U1MFK c = new EntityC_U1MFK(); c.setName("c"); @@ -227,7 +227,7 @@ extends AbstractCachedEMFTestCase { EntityC_U1MFK c2 = cs.remove(0); Uni_1ToM_FK u2 = new Uni_1ToM_FK(); - u2.setName("uni1mfk2"); + u2.setName("u2"); List cs2 = new ArrayList(); cs2.add(c2); u2.setEntityCs(cs2); @@ -256,7 +256,7 @@ extends AbstractCachedEMFTestCase { // default public void crudUni1MJT(EntityManager em) { Uni_1ToM_JT u = new Uni_1ToM_JT(); - u.setName("uni1mjt"); + u.setName("u"); List cs = new ArrayList(); EntityC c = new EntityC(); c.setName("c"); @@ -299,7 +299,7 @@ extends AbstractCachedEMFTestCase { //default public void crudBi1MFK(EntityManager em) { Bi_1ToM_FK b = new Bi_1ToM_FK(); - b.setName("bi1mfk"); + b.setName("b"); List cs = new ArrayList(); EntityC_B1MFK c = new EntityC_B1MFK(); c.setName("c"); @@ -324,7 +324,7 @@ extends AbstractCachedEMFTestCase { em.clear(); //query - Query q = em.createQuery("SELECT u FROM Bi_1ToM_FK u"); + Query q = em.createQuery("SELECT b FROM Bi_1ToM_FK b"); Bi_1ToM_FK b1 = (Bi_1ToM_FK)q.getSingleResult(); assertEquals(b, b1); em.clear(); @@ -343,7 +343,7 @@ extends AbstractCachedEMFTestCase { public void crudBi1MJT(EntityManager em) { Bi_1ToM_JT b = new Bi_1ToM_JT(); - b.setName("bi1mfk"); + b.setName("b"); List cs = new ArrayList(); EntityC_B1MJT c = new EntityC_B1MJT(); c.setName("c"); @@ -429,7 +429,7 @@ extends AbstractCachedEMFTestCase { public void crudUni1MMapFK(EntityManager em) { //create Uni_1ToM_Map_FK u = new Uni_1ToM_Map_FK(); - u.setName("uni1mfk"); + u.setName("u"); Map cs = new HashMap(); EntityC_U1M_Map_FK c1 = new EntityC_U1M_Map_FK(); c1.setName("c1"); @@ -447,7 +447,7 @@ extends AbstractCachedEMFTestCase { //update by adding a new C cs = u.getEntityCs(); - u.setName("uni1mfk_new"); + u.setName("newName"); EntityC_U1M_Map_FK c3 = new EntityC_U1M_Map_FK(); c3.setName("c3"); cs.put(c3.getName(), c3); @@ -461,7 +461,7 @@ extends AbstractCachedEMFTestCase { EntityC_U1M_Map_FK c4 = cs.remove("c1"); Uni_1ToM_Map_FK u2 = new Uni_1ToM_Map_FK(); - u2.setName("uni1mfk2"); + u2.setName("u2"); Map cs2 = new HashMap(); cs2.put(c4.getName(), c4); u2.setEntityCs(cs2); @@ -470,7 +470,7 @@ extends AbstractCachedEMFTestCase { em.clear(); //query - Query q = em.createQuery("SELECT u FROM Uni_1ToM_Map_FK u where u.name='uni1mfk_new'"); + Query q = em.createQuery("SELECT u FROM Uni_1ToM_Map_FK u where u.name='newName'"); Uni_1ToM_Map_FK u1 = (Uni_1ToM_Map_FK)q.getSingleResult(); assertEquals(u, u1); em.clear(); @@ -488,7 +488,7 @@ extends AbstractCachedEMFTestCase { public void crudBi1MMapJT(EntityManager em) { Bi_1ToM_Map_JT b = new Bi_1ToM_Map_JT(); - b.setName("bi1mfk"); + b.setName("b"); Map cs = new HashMap(); EntityC_B1M_Map_JT c = new EntityC_B1M_Map_JT(); c.setName("c"); @@ -513,7 +513,7 @@ extends AbstractCachedEMFTestCase { em.clear(); //query - Query q = em.createQuery("SELECT u FROM Bi_1ToM_Map_JT u"); + Query q = em.createQuery("SELECT b FROM Bi_1ToM_Map_JT b"); Bi_1ToM_Map_JT b1 = (Bi_1ToM_Map_JT)q.getSingleResult(); assertEquals(b, b1); em.clear(); @@ -521,7 +521,7 @@ extends AbstractCachedEMFTestCase { // query the owner q = em.createQuery("SELECT c FROM EntityC_B1M_Map_JT c"); List cs1 = q.getResultList(); - System.err.println("cs1 size = " + cs1.size()); + assertEquals(2, cs.size()); em.clear(); //find @@ -538,7 +538,7 @@ extends AbstractCachedEMFTestCase { public void crudUni1MMapRelKeyFK(EntityManager em) { //create Uni_1ToM_Map_RelKey_FK u = new Uni_1ToM_Map_RelKey_FK(); - u.setName("uni1mfk"); + u.setName("u"); Map cs = new HashMap(); EntityC_U1M_Map_RelKey_FK c1 = new EntityC_U1M_Map_RelKey_FK(); c1.setName("c1"); @@ -563,7 +563,7 @@ extends AbstractCachedEMFTestCase { //update by adding a new C em.getTransaction().begin(); cs = u.getEntityCs(); - u.setName("uni1mfk_new"); + u.setName("newName"); EntityC_U1M_Map_RelKey_FK c3 = new EntityC_U1M_Map_RelKey_FK(); c3.setName("c3"); EntityC cKey3 = new EntityC(); @@ -578,7 +578,7 @@ extends AbstractCachedEMFTestCase { EntityC_U1M_Map_RelKey_FK c4 = cs.remove(cKey1); Uni_1ToM_Map_RelKey_FK u2 = new Uni_1ToM_Map_RelKey_FK(); - u2.setName("uni1mfk2"); + u2.setName("u2"); Map cs2 = new HashMap(); cs2.put(cKey1, c4); u2.setEntityCs(cs2); @@ -587,7 +587,7 @@ extends AbstractCachedEMFTestCase { em.clear(); //query - Query q = em.createQuery("SELECT u FROM Uni_1ToM_Map_RelKey_FK u where u.name='uni1mfk_new'"); + Query q = em.createQuery("SELECT u FROM Uni_1ToM_Map_RelKey_FK u where u.name='newName'"); Uni_1ToM_Map_RelKey_FK u1 = (Uni_1ToM_Map_RelKey_FK)q.getSingleResult(); assertEquals(u, u1); em.clear(); @@ -605,7 +605,7 @@ extends AbstractCachedEMFTestCase { public void crudBi1MMapRelKeyJT(EntityManager em) { Bi_1ToM_Map_RelKey_JT b = new Bi_1ToM_Map_RelKey_JT(); - b.setName("bi1mfk"); + b.setName("b"); Map cs = new HashMap(); EntityC_B1M_Map_RelKey_JT c = new EntityC_B1M_Map_RelKey_JT(); c.setName("c"); @@ -636,7 +636,7 @@ extends AbstractCachedEMFTestCase { em.clear(); //query - Query q = em.createQuery("SELECT u FROM Bi_1ToM_Map_RelKey_JT u"); + Query q = em.createQuery("SELECT b FROM Bi_1ToM_Map_RelKey_JT b"); Bi_1ToM_Map_RelKey_JT b1 = (Bi_1ToM_Map_RelKey_JT)q.getSingleResult(); assertEquals(b, b1); em.clear(); @@ -658,6 +658,201 @@ extends AbstractCachedEMFTestCase { em.getTransaction().commit(); } + public void testUniManyToOneUsingJoinTable() { + List> types = new ArrayList>(); + types.add(EntityC.class); + types.add(Uni_MTo1_JT.class); + OpenJPAEntityManagerFactorySPI emf = createEMF2_0(types); + EntityManager em = emf.createEntityManager(); + + try { + // trigger table creation + em.getTransaction().begin(); + em.getTransaction().commit(); + assertSQLFragnments(sql, "CREATE TABLE UniM1JT_C", "U_ID", "C_ID"); + crudUniM1JT(em); + } catch (Exception e) { + e.printStackTrace(); + fail("ManyToOne mapping failed with exception message: " + e.getMessage()); + } finally { + em.close(); + emf.close(); + } + } + + public void crudUniM1JT(EntityManager em) { + //create + Uni_MTo1_JT u = new Uni_MTo1_JT(); + u.setName("u"); + + Uni_MTo1_JT u1 = new Uni_MTo1_JT(); + u1.setName("u1"); + + EntityC c1 = new EntityC(); + c1.setName("c1"); + u.setEntityC(c1); + u1.setEntityC(c1); + + em.persist(u); + em.persist(u1); + em.persist(c1); + em.getTransaction().begin(); + em.getTransaction().commit(); + + //update by changing the many-to-one value + em.getTransaction().begin(); + u.setName("u_new"); + EntityC c3 = new EntityC(); + c3.setName("c3"); + u.setEntityC(c3); + em.persist(c3); + em.getTransaction().commit(); + + // update be removing the many-to-one value + em.getTransaction().begin(); + u.setEntityC(null); + em.getTransaction().commit(); + + //query + Query q = em.createQuery("SELECT u FROM Uni_MTo1_JT u where u.name='u_new'"); + Uni_MTo1_JT queryU = (Uni_MTo1_JT)q.getSingleResult(); + assertEquals(u, queryU); + em.clear(); + + //find + long id = u1.getId(); + Uni_MTo1_JT findU = em.find(Uni_MTo1_JT.class, id); + assertEquals(u1, findU); + + //remove + em.getTransaction().begin(); + em.remove(findU); + em.getTransaction().commit(); + } + + public void testOneToOneUsingJoinTable() { + List> types = new ArrayList>(); + types.add(EntityC_B11JT.class); + types.add(EntityC_U11JT.class); + types.add(Bi_1To1_JT.class); + types.add(Uni_1To1_JT.class); + OpenJPAEntityManagerFactorySPI emf = createEMF2_0(types); + EntityManager em = emf.createEntityManager(); + + try { + // trigger table creation + em.getTransaction().begin(); + em.getTransaction().commit(); + assertSQLFragnments(sql, "CREATE TABLE Bi11JT_C", "B_ID", "C_ID"); + assertSQLFragnments(sql, "CREATE TABLE Uni11JT_C", "U_ID", "C_ID"); + crudBi11JT(em); + crudUni11JT(em); + } catch (Exception e) { + e.printStackTrace(); + fail("OneToOne mapping failed with exception message: " + e.getMessage()); + } finally { + em.close(); + emf.close(); + } + } + + public void crudUni11JT(EntityManager em) { + Uni_1To1_JT u = new Uni_1To1_JT(); + u.setName("uni1mjt"); + + EntityC_U11JT c1 = new EntityC_U11JT(); + c1.setName("c1"); + u.setEntityC(c1); + + em.persist(u); + em.persist(c1); + em.getTransaction().begin(); + em.getTransaction().commit(); + + //update by setting to a new C + em.getTransaction().begin(); + u.setName("uni1mjt_new"); + EntityC_U11JT newC = new EntityC_U11JT(); + newC.setName("newC"); + u.setEntityC(newC); + em.persist(newC); + em.getTransaction().commit(); + + // update by setting to null + em.getTransaction().begin(); + u.setEntityC(null); + em.getTransaction().commit(); + em.clear(); + + //query + Query q = em.createQuery("SELECT u FROM Uni_1To1_JT u where u.name = 'uni1mjt_new'"); + Uni_1To1_JT u1 = (Uni_1To1_JT)q.getSingleResult(); + assertEquals(u, u1); + em.clear(); + + //find + long id = u1.getId(); + Uni_1To1_JT findU1 = em.find(Uni_1To1_JT.class, id); + assertEquals(u, findU1); + + //remove + em.getTransaction().begin(); + em.remove(findU1); + em.getTransaction().commit(); + } + + public void crudBi11JT(EntityManager em) { + Bi_1To1_JT b = new Bi_1To1_JT(); + b.setName("bi11fk"); + + EntityC_B11JT c = new EntityC_B11JT(); + c.setName("c"); + b.setEntityC(c); + //c.setBi11jt(b); + + em.persist(b); + em.persist(c); + em.getTransaction().begin(); + em.getTransaction().commit(); + + // update by removing a c + em.getTransaction().begin(); + b.setEntityC(null); + em.getTransaction().commit(); + + //update + em.getTransaction().begin(); + b.setName("newName"); + EntityC_B11JT c1 = new EntityC_B11JT(); + c1.setName("c1"); + b.setEntityC(c1); + //c1.setBi11jt(b); + em.persist(c1); + em.getTransaction().commit(); + + //query + Query q = em.createQuery("SELECT u FROM Bi_1To1_JT u"); + Bi_1To1_JT b1 = (Bi_1To1_JT)q.getSingleResult(); + assertEquals(b, b1); + em.clear(); + + // query + q = em.createQuery("SELECT c FROM EntityC_B11JT c"); + List cs1 = q.getResultList(); + assertEquals(2, cs1.size()); + em.clear(); + + //find + long id = b1.getId(); + Bi_1To1_JT b2 = em.find(Bi_1To1_JT.class, id); + assertEquals(b, b2); + + //remove + em.getTransaction().begin(); + em.remove(b2); + em.getTransaction().commit(); + } + private OpenJPAEntityManagerFactorySPI createEMF2_0(List> types) { Map map = new HashMap(); map.put("openjpa.jdbc.JDBCListeners", diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1To1_JT.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1To1_JT.java new file mode 100644 index 000000000..cb28ff11f --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1To1_JT.java @@ -0,0 +1,75 @@ +/* + * 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.compat; + +import javax.persistence.*; + +@Entity +public class Uni_1To1_JT { + + @Id + @GeneratedValue + private long id; + + private String name; + + @OneToOne + @JoinTable( + name="Uni11JT_C", + joinColumns= + @JoinColumn(name="U_ID", referencedColumnName="ID"), + inverseJoinColumns= + @JoinColumn(name="C_ID", referencedColumnName="ID") + ) + private EntityC_U11JT entityC; + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public EntityC_U11JT getEntityC() { + return entityC; + } + + public void setEntityC(EntityC_U11JT entityC) { + this.entityC = entityC; + } + + public int hashCode() { + return name.hashCode() + (int)id; + } + + public boolean equals(Object o) { + if (!(o instanceof Uni_1To1_JT)) return false; + Uni_1To1_JT u = (Uni_1To1_JT)o; + if (!u.name.equals(name)) return false; + if (u.id != id) return false; + if (u.entityC == null && entityC == null) return true; + if (u.entityC.getId() != entityC.getId()) return false; + return true; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_MTo1_JT.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_MTo1_JT.java new file mode 100644 index 000000000..85fa2d6b3 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_MTo1_JT.java @@ -0,0 +1,75 @@ +/* + * 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.compat; + +import javax.persistence.*; + +@Entity +public class Uni_MTo1_JT { + + @Id + @GeneratedValue + private long id; + + private String name; + + @ManyToOne + @JoinTable( + name="UniM1JT_C", + joinColumns= + @JoinColumn(name="U_ID", referencedColumnName="ID"), + inverseJoinColumns= + @JoinColumn(name="C_ID", referencedColumnName="ID") + ) + private EntityC entityC; + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public EntityC getEntityC() { + return entityC; + } + + public void setEntityC(EntityC entityC) { + this.entityC = entityC; + } + + public int hashCode() { + return name.hashCode() + (int)id; + } + + public boolean equals(Object o) { + if (!(o instanceof Uni_MTo1_JT)) return false; + Uni_MTo1_JT c = (Uni_MTo1_JT)o; + if (!c.name.equals(name)) return false; + if (c.id != id) return false; + if (c.entityC == null && entityC == null) return true; + if (!c.entityC.equals(entityC)) return false; + return true; + } +}