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() {
+		
+	}
+}