From 4d5a6c5e562e7afa4305703807a9b67bd74688eb Mon Sep 17 00:00:00 2001 From: Fay Wang Date: Wed, 4 Feb 2009 16:31:54 +0000 Subject: [PATCH] OPENJPA-870: orm support for OrphanRemoval git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@740781 13f79535-47bb-0310-9956-ffa450edef68 --- .../persistence/embed/ContactInfo.java | 18 +++ .../persistence/embed/CustomerXml.java | 84 ++++++++++++++ .../openjpa/persistence/embed/JobInfo.java | 19 ++- .../persistence/embed/LocationDetails.java | 18 +++ .../openjpa/persistence/embed/OrderXml.java | 61 ++++++++++ .../persistence/embed/ParkingSpot.java | 18 +++ .../persistence/embed/PhoneNumber.java | 18 +++ .../persistence/embed/ProgramManager.java | 18 +++ .../persistence/embed/TestEmbeddableXml.java | 108 +++++++++++++++++- .../test/resources/META-INF/persistence.xml | 3 + .../openjpa/persistence/embed/embed-orm.xml | 90 +++++++++------ .../XMLPersistenceMetaDataParser.java | 13 ++- 12 files changed, 430 insertions(+), 38 deletions(-) create mode 100644 openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/CustomerXml.java create mode 100644 openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/OrderXml.java diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/ContactInfo.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/ContactInfo.java index 9d07ebc48..cd0d63ae8 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/ContactInfo.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/ContactInfo.java @@ -1,3 +1,21 @@ +/* + * 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.embed; import javax.persistence.*; diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/CustomerXml.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/CustomerXml.java new file mode 100644 index 000000000..a685fe9b3 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/CustomerXml.java @@ -0,0 +1,84 @@ +/* + * 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.embed; + +import java.util.HashSet; +import java.util.Set; + +public class CustomerXml { + protected int id; + + protected String name; + + protected Set orders = new HashSet(); + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Set getOrders() { + return orders; + } + + public void setOrders(Set orders) { + this.orders = orders; + } + + public void addOrder(OrderXml order) { + orders.add(order); + } + + public boolean equals(Object obj) { + CustomerXml c0 = (CustomerXml) obj; + if (c0 == null) return false; + if (c0.getId() != id) return false; + if (!c0.getName().equals(name)) return false; + Set orders0 = c0.getOrders(); + if (orders0.size() != orders.size()) + return false; + for (OrderXml o : orders) { + if (!contains(orders0, o)) + return false; + } + return true; + } + + private boolean contains(Set orders0, OrderXml o) { + int id = o.getId(); + for (OrderXml o0 : orders0) { + if (o0.getId() == id) + return true; + } + return false; + } +} + + diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/JobInfo.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/JobInfo.java index ab34d5012..0d93e6683 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/JobInfo.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/JobInfo.java @@ -1,7 +1,24 @@ +/* + * 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.embed; import javax.persistence.*; -import java.util.*; @Embeddable public class JobInfo { diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/LocationDetails.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/LocationDetails.java index 07fef625e..7a8b920aa 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/LocationDetails.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/LocationDetails.java @@ -1,3 +1,21 @@ +/* + * 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.embed; import javax.persistence.*; diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/OrderXml.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/OrderXml.java new file mode 100644 index 000000000..8632cc34f --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/OrderXml.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.embed; + + +public class OrderXml { + protected int id; + + protected String description; + + protected CustomerXml cust; + + public CustomerXml getCust() { + return cust; + } + + public void setCust(CustomerXml cust) { + this.cust = cust; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public void setDescription(String desc) { + this.description = desc; + } + + public boolean equals(Object obj) { + OrderXml o0 = (OrderXml) obj; + if (o0 == null) return false; + if (o0.getId() != id) return false; + if (!o0.getDescription().equals(description)) return false; + if (!o0.getCust().equals(cust)) return false; + return true; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/ParkingSpot.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/ParkingSpot.java index d1f0afe3f..8752603fa 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/ParkingSpot.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/ParkingSpot.java @@ -1,3 +1,21 @@ +/* + * 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.embed; import javax.persistence.*; diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/PhoneNumber.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/PhoneNumber.java index 883d54c09..fd7c67b58 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/PhoneNumber.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/PhoneNumber.java @@ -1,3 +1,21 @@ +/* + * 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.embed; import javax.persistence.*; diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/ProgramManager.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/ProgramManager.java index 39bc12e39..e2281f907 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/ProgramManager.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/ProgramManager.java @@ -1,3 +1,21 @@ +/* + * 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.embed; import javax.persistence.*; diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddableXml.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddableXml.java index ed06bd85d..62b6f885c 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddableXml.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddableXml.java @@ -44,12 +44,16 @@ public class TestEmbeddableXml extends SingleEMFTestCase { public int newVpId = 100; public int numItems = 2; public int itemId = 1; + public int cId = 1; + public int oId = 1; public int numImagesPerItem = 3; public int numDepartments = 2; public int numEmployeesPerDept = 2; public int numCompany = 2; public int numDivisionsPerCo = 2; + public int numCustomers = 1; + public int numOrdersPerCustomer = 2; public void setUp() { setUp(CLEAR_TABLES); @@ -625,5 +629,107 @@ public class TestEmbeddableXml extends SingleEMFTestCase { public void assertVicePresident(VicePresidentXml vp) { int id = vp.getId(); String name = vp.getName(); - } + } + + public void createOrphanRemoval() { + EntityManager em = emf.createEntityManager(); + EntityTransaction tran = em.getTransaction(); + for (int i = 0; i < numCustomers; i++) + createCustomer(em, cId++); + tran.begin(); + em.flush(); + tran.commit(); + em.close(); + } + + public CustomerXml createCustomer(EntityManager em, int id) { + CustomerXml c = new CustomerXml(); + c.setId(id); + c.setName("name" + id); + for (int i = 0; i < numOrdersPerCustomer; i++) { + OrderXml order = createOrder(em, oId++); + c.addOrder(order); + order.setCust(c); + em.persist(order); + } + em.persist(c); + return c; + } + + public OrderXml createOrder(EntityManager em, int id) { + OrderXml o = new OrderXml(); + o.setId(id); + em.persist(o); + return o; + } + + public void testOrphanRemovalTarget() { + createOrphanRemoval(); + EntityManager em = emf.createEntityManager(); + int count = count(OrderXml.class); + assertEquals(numOrdersPerCustomer * numCustomers, count); + + CustomerXml c = em.find(CustomerXml.class, 1); + Set orders = c.getOrders(); + assertEquals(numOrdersPerCustomer, orders.size()); + + // OrphanRemoval: remove target: the order will be deleted from db + for (OrderXml order : orders) { + orders.remove(order); + break; + } + em.getTransaction().begin(); + em.persist(c); + em.flush(); + em.getTransaction().commit(); + em.clear(); + + c = em.find(CustomerXml.class, 1); + orders = c.getOrders(); + assertEquals(numOrdersPerCustomer - 1, orders.size()); + count = count(OrderXml.class); + assertEquals(numOrdersPerCustomer * numCustomers - 1, count); + em.close(); + } + + public void testOrphanRemovalTargetSetNull() { + createOrphanRemoval(); + EntityManager em = emf.createEntityManager(); + CustomerXml c = em.find(CustomerXml.class, 1); + System.err.println("C name = " + c.getName()); + System.err.println("size before = " + c.getOrders().size()); + c.setOrders(null); + em.getTransaction().begin(); + em.persist(c); + em.flush(); + em.getTransaction().commit(); + em.clear(); + + int count = count(OrderXml.class); + assertEquals(numOrdersPerCustomer * (numCustomers - 1), count); + + c = em.find(CustomerXml.class, 1); + Set orders = c.getOrders(); + if (orders != null) + assertEquals(0, orders.size()); + em.close(); + } + + public void testOrphanRemovalSource() { + createOrphanRemoval(); + EntityManager em = emf.createEntityManager(); + + // OrphanRemoval: remove source + CustomerXml c = em.find(CustomerXml.class, 1); + em.getTransaction().begin(); + em.remove(c); + em.flush(); + em.getTransaction().commit(); + em.clear(); + + int count = count(OrderXml.class); + assertEquals(numOrdersPerCustomer * (numCustomers - 1), count); + + em.close(); + } } diff --git a/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml b/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml index d11531faa..71459bb1d 100644 --- a/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml +++ b/openjpa-persistence-jdbc/src/test/resources/META-INF/persistence.xml @@ -39,6 +39,7 @@ class. org/apache/openjpa/persistence/xml/orm.xml + org/apache/openjpa/persistence/embed/embed-orm.xml @@ -107,6 +108,8 @@ org.apache.openjpa.persistence.embed.EntityA_Coll_Embed_EmbedXml org.apache.openjpa.persistence.embed.Embed_EmbedXml org.apache.openjpa.persistence.embed.EmbedXml + org.apache.openjpa.persistence.embed.CustomerXml + org.apache.openjpa.persistence.embed.OrderXml diff --git a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/embed/embed-orm.xml b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/embed/embed-orm.xml index 1fc99a00c..5ef817264 100644 --- a/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/embed/embed-orm.xml +++ b/openjpa-persistence-jdbc/src/test/resources/org/apache/openjpa/persistence/embed/embed-orm.xml @@ -123,40 +123,60 @@ version="2.0"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java index 6a6fc01a4..0ea765861 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java @@ -1392,6 +1392,9 @@ public class XMLPersistenceMetaDataParser fmd.setSerialized(false); // override any Lob annotation if (!fmd.isDefaultFetchGroupExplicit()) fmd.setInDefaultFetchGroup(true); + boolean orphanRemoval = Boolean.valueOf(attrs.getValue( + "orphan-removal")); + setOrphanRemoval(fmd, orphanRemoval); } /** @@ -1448,8 +1451,16 @@ public class XMLPersistenceMetaDataParser fmd.getElement().setDeclaredType(classForName(val)); assertPCCollection(fmd, "OneToMany"); fmd.setSerialized(false); // override any Lob annotation + boolean orphanRemoval = Boolean.valueOf(attrs.getValue( + "orphan-removal")); + setOrphanRemoval(fmd.getElement(), orphanRemoval); } - + + protected void setOrphanRemoval(ValueMetaData vmd, boolean orphanRemoval) { + if (orphanRemoval) + vmd.setCascadeDelete(ValueMetaData.CASCADE_AUTO); + } + protected void parseElementCollection(FieldMetaData fmd, Attributes attrs) throws SAXException { String val = attrs.getValue("target-entity");