mirror of https://github.com/apache/openjpa.git
OPENJPA-755 Update to SingleFieldManager to permit detached related entities on a merge with cascade persist. Committing for Dinkar Rao.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@709527 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
1a378e13f9
commit
54d4d0d07d
|
@ -744,6 +744,7 @@ class SingleFieldManager
|
|||
return;
|
||||
|
||||
OpenJPAStateManager sm;
|
||||
|
||||
if (vmd.getCascadePersist() == ValueMetaData.CASCADE_NONE) {
|
||||
if (!_broker.isDetachedNew() && _broker.isDetached(obj))
|
||||
return; // allow but ignore
|
||||
|
@ -754,6 +755,10 @@ class SingleFieldManager
|
|||
_loc.get("cant-cascade-persist", vmd))
|
||||
.setFailedObject(obj);
|
||||
} else {
|
||||
if (vmd.getCascadePersist() == ValueMetaData.CASCADE_IMMEDIATE) {
|
||||
if (!_broker.isDetachedNew() && _broker.isDetached(obj))
|
||||
return; // allow but ignore
|
||||
}
|
||||
sm = _broker.getStateManager(obj);
|
||||
if (sm == null || !sm.isProvisional()) {
|
||||
sm = _broker.persist(obj, null, true, call);
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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.detachment;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.apache.openjpa.persistence.detachment.model.DMCustomer;
|
||||
import org.apache.openjpa.persistence.detachment.model.DMCustomerInventory;
|
||||
import org.apache.openjpa.persistence.detachment.model.DMItem;
|
||||
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
||||
|
||||
public class TestDetachedEntityCascadePersist extends SingleEMFTestCase {
|
||||
|
||||
public void setUp() {
|
||||
setUp(
|
||||
CLEAR_TABLES,
|
||||
DMCustomer.class,
|
||||
DMItem.class,
|
||||
DMCustomerInventory.class
|
||||
);
|
||||
}
|
||||
|
||||
public void testDetachedEntityCascadePersist() {
|
||||
// Persist an item for finding later
|
||||
EntityManager em = emf.createEntityManager();
|
||||
DMItem item = new DMItem();
|
||||
item.setName("openjpa");
|
||||
item.setPrice(0.0);
|
||||
em.getTransaction().begin();
|
||||
em.persist(item);
|
||||
// Persist a customer for finding later
|
||||
DMCustomer customer = new DMCustomer();
|
||||
customer.setFirstName("Open");
|
||||
customer.setLastName("JPA");
|
||||
em.persist(customer);
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
|
||||
em = emf.createEntityManager();
|
||||
DMItem itemDetached = em.find(DMItem.class, item.getId());
|
||||
em.close();
|
||||
em = emf.createEntityManager();
|
||||
DMCustomer customer2 = em.find(DMCustomer.class, customer.getId());
|
||||
DMCustomerInventory customerInventory = new DMCustomerInventory();
|
||||
customerInventory.setCustomer(customer2);
|
||||
customerInventory.setItem(itemDetached);
|
||||
customerInventory.setQuantity(20);
|
||||
customer2.getCustomerInventories().add(customerInventory);
|
||||
em.getTransaction().begin();
|
||||
em.merge(customer2);
|
||||
// At this point, itemDetached is still detached.
|
||||
// The following commit causes a persist on CustomerInventory,
|
||||
// which leads to a cascade-persist on the detached item.
|
||||
// This cascade-persist on a detached item should be ignored,
|
||||
// instead of a EntityExistsException being thrown
|
||||
em.getTransaction().commit();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.detachment.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
|
||||
@Entity
|
||||
public class DMCustomer {
|
||||
|
||||
private static long idCounter = System.currentTimeMillis();
|
||||
@Id private long id = idCounter++;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
@OneToMany(mappedBy="customer",
|
||||
fetch=FetchType.EAGER,
|
||||
cascade=CascadeType.ALL)
|
||||
private List<DMCustomerInventory> customerInventories = new ArrayList<DMCustomerInventory>();
|
||||
|
||||
public DMCustomer() {
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public List<DMCustomerInventory> getCustomerInventories() {
|
||||
return customerInventories;
|
||||
}
|
||||
|
||||
public void setCustomerInventories(List<DMCustomerInventory> customerInventories) {
|
||||
this.customerInventories = customerInventories;
|
||||
}
|
||||
}
|
|
@ -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.detachment.model;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
@Entity
|
||||
public class DMCustomerInventory {
|
||||
private static long idCounter = System.currentTimeMillis();
|
||||
@Id private long id = idCounter++;
|
||||
|
||||
@ManyToOne(cascade=CascadeType.ALL)
|
||||
@JoinColumn(name = "CI_ITEMID")
|
||||
private DMItem item;
|
||||
private int quantity;
|
||||
|
||||
@ManyToOne(cascade=CascadeType.MERGE)
|
||||
@JoinColumn(name="CI_CUSTOMERID")
|
||||
private DMCustomer customer;
|
||||
|
||||
public DMCustomerInventory() {
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public DMItem getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public void setItem(DMItem item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
public int getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(int quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public DMCustomer getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
|
||||
public void setCustomer(DMCustomer customer) {
|
||||
this.customer = customer;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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.detachment.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class DMItem {
|
||||
private static long idCounter = System.currentTimeMillis();
|
||||
@Id private long id = idCounter++;
|
||||
|
||||
private String name;
|
||||
private double price;
|
||||
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public double getPrice() {
|
||||
return price;
|
||||
}
|
||||
public void setPrice(double price) {
|
||||
this.price = price;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue