You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2008/08/10 12:12:38 UTC
svn commit: r684443 - in
/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi:
./ Address.java Person.java TestBiDirectionalJoinTable.java
Author: ppoddar
Date: Sun Aug 10 03:12:37 2008
New Revision: 684443
URL: http://svn.apache.org/viewvc?rev=684443&view=rev
Log:
OPENJPA-692: Add Test cases for Bi-directional mapping with JoinTable
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/Address.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/Person.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/TestBiDirectionalJoinTable.java
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/Address.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/Address.java?rev=684443&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/Address.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/Address.java Sun Aug 10 03:12:37 2008
@@ -0,0 +1,80 @@
+/*
+ * 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.bidi;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+/**
+ * Demonstrate usage of a JoinTable for a bi-directional one-to-many mapping.
+ *
+ *
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+@Table(name="J_ADDRESS")
+public class Address {
+ @Id
+ private String phone;
+
+ private String city;
+ private int zip;
+
+ @ManyToOne
+ @JoinColumn(table="J_PERSON_ADDRESSES", referencedColumnName="SSN")
+ private Person person;
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public int getZip() {
+ return zip;
+ }
+
+ public void setZip(int zip) {
+ this.zip = zip;
+ }
+
+ public Person getPerson() {
+ return person;
+ }
+
+ public void setPerson(Person person) {
+ this.person = person;
+ }
+}
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/Person.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/Person.java?rev=684443&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/Person.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/Person.java Sun Aug 10 03:12:37 2008
@@ -0,0 +1,87 @@
+/*
+ * 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.bidi;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+import org.apache.openjpa.jdbc.meta.strats.RelationCollectionTableFieldStrategy;
+import org.apache.openjpa.persistence.jdbc.Strategy;
+
+/**
+ * Demonstrate usage of a JoinTable for a bi-directional one-to-many mapping.
+ *
+ *
+ * @author Pinaki Poddar
+ *
+ */
+@Entity
+@Table(name="J_PERSON")
+public class Person {
+ @Id
+ private long ssn;
+
+ private String name;
+
+ @OneToMany(cascade=CascadeType.ALL)
+ @JoinTable(name="J_PERSON_ADDRESSES",
+ joinColumns = @JoinColumn(name="PERSON_SSN", referencedColumnName="SSN"),
+ inverseJoinColumns = @JoinColumn(name="ADDRESS_PHONE", referencedColumnName="PHONE"))
+ private Set<Address> addresses = new HashSet<Address>();
+
+ public long getSsn() {
+ return ssn;
+ }
+
+ public Set<Address> getAddresses() {
+ return addresses;
+ }
+
+ /**
+ * Keep bi-directional relation consistent.
+ */
+ public void addAddress(Address address) {
+ if (addresses == null)
+ addresses = new HashSet<Address>();
+ addresses.add(address);
+ address.setPerson(this);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setSsn(long ssn) {
+ this.ssn = ssn;
+ }
+}
+
\ No newline at end of file
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/TestBiDirectionalJoinTable.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/TestBiDirectionalJoinTable.java?rev=684443&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/TestBiDirectionalJoinTable.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/TestBiDirectionalJoinTable.java Sun Aug 10 03:12:37 2008
@@ -0,0 +1,159 @@
+/*
+ * 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.bidi;
+
+import java.util.Arrays;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
+
+/**
+ * Tests basic persistence operations on bi-directional mapping that uses a
+ * JoinTable.
+ *
+ * Originally reported as an error which shows that
+ * a) rows in join table get repeated insert as bi-directional mapping is
+ * essentially modeled as two uni-directional mapping
+ * b) update/delete fails with OptimisticExecption because of repeated operation
+ * on the join table row
+ *
+ * Further details available at
+ * <A HREF="https://issues.apache.org/jira/browse/OPENJPA-692">OPENJPA-692</A>
+ * and
+ * <A HREF="http://n2.nabble.com/bidirectional-one-to-many-relationship-with-join-table-tc678479.html">Nabble posts</A>
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class TestBiDirectionalJoinTable extends SQLListenerTestCase {
+ private static long SSN = 123456789;
+ private static String[] PHONES = {"+1-23-456", "+2-34-567", "+3-45-678"};
+ private static int ADDRESS_COUNT = PHONES.length;
+ private static String[] CITIS = {"Berlin", "Paris", "Rome"};
+ private static int[] ZIPS = {123456, 234567, 345678};
+
+ public void setUp() {
+ super.setUp(CLEAR_TABLES, Person.class, Address.class);
+ createData(SSN);
+ sql.clear();
+ }
+
+ public void testPersist() {
+ EntityManager em = emf.createEntityManager();
+ Person person = em.find(Person.class, SSN);
+ assertNotNull(person);
+
+ assertEquals(ADDRESS_COUNT, person.getAddresses().size());
+ }
+
+ public void testQuery() {
+ EntityManager em = emf.createEntityManager();
+ String jpql = "select distinct a.city from Person as p, in(p.addresses) a";
+ Query query = em.createQuery(jpql);
+ assertEquals(ADDRESS_COUNT, query.getResultList().size());
+ }
+
+ public void testUpdate() {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ Person person = em.find(Person.class, SSN);
+ Address newAddress = new Address();
+ newAddress.setPhone("+4-56-789");
+ newAddress.setCity("San Francisco");
+ person.addAddress(newAddress);
+ person.setName("Frank");
+ em.merge(person);
+ em.getTransaction().commit();
+
+ em = emf.createEntityManager();
+ Person updated = em.find(Person.class, SSN);
+ assertEquals("Frank", updated.getName());
+ assertEquals(ADDRESS_COUNT+1, updated.getAddresses().size());
+ }
+
+ public void testRemove() {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ Person person = em.find(Person.class, SSN);
+ em.remove(person);
+ em.getTransaction().commit();
+
+ assertEquals(0, count(Person.class));
+ assertEquals(0, count(Address.class));
+ assertSQL("DELETE FROM .*J_PERSON_ADDRESSES .*");
+ }
+
+ public void testSingleDelete() {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ String jpql = "delete from Person p where p.ssn=:ssn";
+ em.createQuery(jpql).setParameter("ssn", SSN).executeUpdate();
+ em.getTransaction().commit();
+
+ assertEquals(0, count(Person.class));
+ assertEquals(0, count(Address.class));
+ assertSQL("DELETE FROM .*J_PERSON_ADDRESSES .*");
+ }
+
+ public void testBulkDelete() {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ String jpql = "delete from Person p";
+ em.createQuery(jpql).executeUpdate();
+ em.getTransaction().commit();
+
+ assertEquals(0, count(Person.class));
+ assertEquals(0, count(Address.class));
+ assertSQL("DELETE FROM .*J_PERSON_ADDRESSES .*");
+ }
+
+ /**
+ * Create a Person with given SSN and fixed number of addresses.
+ *
+ * @param ssn
+ */
+ void createData(long ssn) {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+
+ sql.clear();
+ Person person = new Person();
+ person.setSsn(SSN);
+ person.setName("Pinaki");
+ for (int i=0; i<PHONES.length; i++) {
+ Address address = new Address();
+ address.setPhone(PHONES[i]);
+ address.setCity(CITIS[i]);
+ address.setZip(ZIPS[i]);
+ person.addAddress(address);
+ }
+ em.persist(person);
+ em.getTransaction().commit();
+ assertEquals(1+2*ADDRESS_COUNT, sql.size());
+ }
+
+
+ @Override
+ public void tearDown() {
+
+ }
+}