mirror of https://github.com/apache/openjpa.git
OPENJPA-870: orm support for OrphanRemoval
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@740781 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d61b3b26a9
commit
4d5a6c5e56
|
@ -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.*;
|
||||
|
|
|
@ -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<OrderXml> orders = new HashSet<OrderXml>();
|
||||
|
||||
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<OrderXml> getOrders() {
|
||||
return orders;
|
||||
}
|
||||
|
||||
public void setOrders(Set<OrderXml> 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<OrderXml> 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<OrderXml> orders0, OrderXml o) {
|
||||
int id = o.getId();
|
||||
for (OrderXml o0 : orders0) {
|
||||
if (o0.getId() == id)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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 {
|
||||
|
|
|
@ -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.*;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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.*;
|
||||
|
|
|
@ -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.*;
|
||||
|
|
|
@ -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.*;
|
||||
|
|
|
@ -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<OrderXml> 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<OrderXml> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
class.
|
||||
</description>
|
||||
<mapping-file>org/apache/openjpa/persistence/xml/orm.xml</mapping-file>
|
||||
<mapping-file>org/apache/openjpa/persistence/embed/embed-orm.xml</mapping-file>
|
||||
<properties>
|
||||
<property name="openjpa.jdbc.SynchronizeMappings"
|
||||
value="buildSchema(ForeignKeys=true)"/>
|
||||
|
@ -107,6 +108,8 @@
|
|||
<class>org.apache.openjpa.persistence.embed.EntityA_Coll_Embed_EmbedXml</class>
|
||||
<class>org.apache.openjpa.persistence.embed.Embed_EmbedXml</class>
|
||||
<class>org.apache.openjpa.persistence.embed.EmbedXml</class>
|
||||
<class>org.apache.openjpa.persistence.embed.CustomerXml</class>
|
||||
<class>org.apache.openjpa.persistence.embed.OrderXml</class>
|
||||
<properties>
|
||||
<property name="openjpa.jdbc.SynchronizeMappings"
|
||||
value="buildSchema(ForeignKeys=true)"/>
|
||||
|
|
|
@ -123,40 +123,60 @@ version="2.0">
|
|||
</one-to-many>
|
||||
</attributes>
|
||||
</entity>
|
||||
|
||||
<embeddable class="org.apache.openjpa.persistence.embed.Embed_EmbedXml"
|
||||
access="FIELD">
|
||||
<attributes>
|
||||
<basic name="intVal1">
|
||||
</basic>
|
||||
<basic name="intVal2">
|
||||
</basic>
|
||||
<basic name="intVal3">
|
||||
</basic>
|
||||
<embedded name="embed">
|
||||
<attribute-override name="intVal1">
|
||||
<column name="embed_intVal1"/>
|
||||
</attribute-override>
|
||||
<attribute-override name="intVal2">
|
||||
<column name="embed_intVal2"/>
|
||||
</attribute-override>
|
||||
<attribute-override name="intVal3">
|
||||
<column name="embed_intVal3"/>
|
||||
</attribute-override>
|
||||
</embedded>
|
||||
</attributes>
|
||||
</embeddable>
|
||||
|
||||
<embeddable class="org.apache.openjpa.persistence.embed.EmbedXml"
|
||||
access="FIELD">
|
||||
<attributes>
|
||||
<basic name="intVal1">
|
||||
</basic>
|
||||
<basic name="intVal2">
|
||||
</basic>
|
||||
<basic name="intVal3">
|
||||
</basic>
|
||||
</attributes>
|
||||
</embeddable>
|
||||
|
||||
<entity name="CustomerXml"
|
||||
class="org.apache.openjpa.persistence.embed.CustomerXml"
|
||||
access="FIELD">
|
||||
<table name="Customer_XML" />
|
||||
<attributes>
|
||||
<id name="id"></id>
|
||||
<basic name="name" />
|
||||
<one-to-many name="orders" mapped-by="cust"
|
||||
orphan-removal="true" />
|
||||
</attributes>
|
||||
</entity>
|
||||
|
||||
<entity name="OrderXml"
|
||||
class="org.apache.openjpa.persistence.embed.OrderXml"
|
||||
access="FIELD">
|
||||
<table name="Order_XML" />
|
||||
<attributes>
|
||||
<id name="id"></id>
|
||||
<basic name="description" />
|
||||
<many-to-one name="cust">
|
||||
<join-column name="CUST_ID" nullable="false" />
|
||||
</many-to-one>
|
||||
</attributes>
|
||||
</entity>
|
||||
|
||||
<embeddable
|
||||
class="org.apache.openjpa.persistence.embed.Embed_EmbedXml"
|
||||
access="FIELD">
|
||||
<attributes>
|
||||
<basic name="intVal1"></basic>
|
||||
<basic name="intVal2"></basic>
|
||||
<basic name="intVal3"></basic>
|
||||
<embedded name="embed">
|
||||
<attribute-override name="intVal1">
|
||||
<column name="embed_intVal1" />
|
||||
</attribute-override>
|
||||
<attribute-override name="intVal2">
|
||||
<column name="embed_intVal2" />
|
||||
</attribute-override>
|
||||
<attribute-override name="intVal3">
|
||||
<column name="embed_intVal3" />
|
||||
</attribute-override>
|
||||
</embedded>
|
||||
</attributes>
|
||||
</embeddable>
|
||||
|
||||
<embeddable class="org.apache.openjpa.persistence.embed.EmbedXml"
|
||||
access="FIELD">
|
||||
<attributes>
|
||||
<basic name="intVal1"></basic>
|
||||
<basic name="intVal2"></basic>
|
||||
<basic name="intVal3"></basic>
|
||||
</attributes>
|
||||
</embeddable>
|
||||
|
||||
</entity-mappings>
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue