2012-03-05 12 views
5

play-1.2.4 का उपयोग करके ऑनलाइन शॉप एप्लिकेशन बनाने के दौरान, मैं जेपीए के साथ कुछ समस्याओं में भाग गया। मैं CRUD module खेल में एक व्यवस्थापक क्षेत्र प्रदान करना चाहता था। यहां, एक व्यवस्थापक उपयोगकर्ता कर सकता है एप्लिकेशन में इकाइयों को बनाएं/संपादित करें या हटाएं (जैसे Customer एस, Order एस, Item एस आदि)।प्लेफ्रेमवर्क में कैस्केडिंग डिलीट-एंटिटीज

एक Customer Orders.Each Order बना सकते हैं CartItem s.When एक Order हटा दी जाती है की एक सेट है, इसी CartItem रों deleted.When किया जाना चाहिए एक Customer हटा दी जाती है, उसके सारे आदेश है.मैं के रूप में हटा दिया जाना चाहिए सोचा कि मैं jpa एनोटेशन में cascade संपत्ति सेट करके इसे प्राप्त कर सकता हूं।

मैं इस

Customer.java

@Entity 
public class Customer extends Model { 
    @Email 
    @Required 
    public String email; 
    ... 
    @OneToMany(mappedBy="customer", cascade=CascadeType.ALL) 
    public List<Order> orders; 
    @OneToOne 
    public PayMethod currentPayment; 
    ... 
} 

है जैसे कि यह मॉडलिंग की Order.java

@Entity 
public class Order extends Model { 
    @OneToMany(cascade=CascadeType.ALL,orphanRemoval=true,fetch=FetchType.EAGER) 
    public Set<CartItem> cartItems; 

    @ManyToOne 
    public Customer customer; 
    @ManyToOne 
    public PayMethod paymentMethod; 
    ... 
} 

CartItem.java

@Entity 
public class CartItem extends Model implements Comparable<CartItem>{  
    @ManyToOne 
    public Item item; 
    public int quantity; 
} 

PayMethod.java

@Entity 
public class PayMethod extends Model { 
    @Required 
    public String cardNumber; 
    @ManyToOne 
    public Customer customer; 
    ... 
} 

निम्नलिखित डेटाबेस तालिकाओं

ग्राहक तालिका

बनाए गए थे
id | email  | fullname | currentpayment_id 
---|-------------|---------------|----------------- 
2 |[email protected]| jon   |29 

आदेश तालिका

id |customer_id | paymentmethod_id 
----+------------+----------------- 
25 | 2   |  29 

cartitem तालिका

id | quantity | item_id 
----+----------+--------- 
26 |  1 |  14 

* order_cartitem तालिका *

+०१२३५१६४१०६
order_id | cartitems_id 
----------+-------------- 
     25 |   26 

CRUD उपयोग कर बनाई गई व्यवस्थापक इंटरफ़ेस में (मैं किसी भी तरीकों implented नहीं किया है, अभी-अभी जो CRUD मॉड्यूल के रूप में उपयोग करते हुए), मैं एक ग्राहक को हटाने का प्रयास है, लेकिन फिर, मैं इस त्रुटि मिलती है,

ERROR: update or delete on table "cartitem" violates foreign key constraint "fk7ff437ad3e28aa91" on table "order_cartitem" 
Detail: Key (id)=(26) is still referenced from table "order_cartitem". 
08:03:03,031 ERROR ~ Could not synchronize database state with session 

क्या मैंने संस्थाओं को मॉडल करने के तरीके में कुछ गड़बड़ की है? मैंने सोचा कि Customer पर डिलीट Order पर कैस्केड किया जाएगा और बदले में यह CartItem एस पर कैस्केड होगा।

क्या मैं इस व्यापक असर पाने के लिए मुझे क्या करना होगा? या मैं मैन्युअल रूप से प्रत्येक CartItem रों के उदाहरण को निकालने के लिए है?

संपादित करें: एसईबी के जवाब

class Order extends Model { 
    @OneToMany(mappedBy="order", cascade=CascadeType.ALL,orphanRemoval=true,fetch=FetchType.EAGER) 
    public Set<CartItem> cartItems; 
    ... 
} 

class CartItem extends Model implements Comparable<CartItem>{ 

    @ManyToOne 
    public Item item; 

    public int quantity; 

    @ManyToOne 
    public Order order; 
... 
} 

static void addItemToCart(Long itemId,Long orderId,String quantity) { 
    Item item = Item.findById(itemId); 
    Order order = Order.findById(orderId); 
    int qty = Integer.parseInt(quantity); 
    CartItem cartItem = new CartItem(item,qty); 
    cartItem.order=order; 
    order.addItem(cartItem, qty); 
    order.save(); 
... 
} 

यह order_cartitem तालिका से छुटकारा और एक क्षेत्र cartitem मेज पर ORDER_ID कहते हो जाता है के अनुसार

cartitem तालिका

 id | quantity | item_id | order_id 
    ----+----------+---------+---------- 
    26 |  1 |  14 |  25  
    27 |  1 |  20 |  25 

admin(CRUD) इंटरफेस, सूचीबद्ध करता Customer और Order s.When एक विशेष Customer (जो Order बनाया) का चयन किया जाता है और हटाएँ बटन क्लिक किया जाता है, यह एक JPA error

JPA error 
A JPA error occurred (Cannot commit): collection owner not associated with session: models.Order.cartItems 
में जो परिणाम

यहां stacktrace

यदि कोई समझ सकता है कि यह क्यों हो रहा है, तो कृपया मुझे बताएं।

दिलचस्प है, मैं किसी खास Order के लिए delete button पर क्लिक कर सकते हैं, और इसे सफलतापूर्वक निम्नलिखित नियंत्रक प्रणाली को बुलाती है,

Admin.java

public static void deleteOrder(Long id) { 
    Order order = Order.findById(id); 
    order.delete();  
    ... 
} 

जो Order और सभी को हटा देता है अपने CartItem रों सफलतापूर्वक .. तो, क्यों ऐसा नहीं होता है जब एक Customer हटा दी जाती है करता है?

+1

कोड मुझे ठीक दिखता है। शायद यह धागा इस मुद्दे के कारण को खोजने में थोड़ा सा मदद करता है: http://stackoverflow.com/questions/2011519/jpa-onetomany-not-deleting-child – Bjarne77

+0

महान लिंक के लिए धन्यवाद .. इसे –

उत्तर

2

अपने cartitem वर्ग

@ManyToOne 
public Order order; 

और एक mappedBy = "आदेश" अपने cartItems में करने के लिए इस जोड़कर अपने संबंध bidirectionnal बनाओ @OneToMany

तो हाइबरनेट बेहतर होगा जो आपके हटाए जाने को संभालती है। मैं अनुमान लगा रहा हूं कि इस बिडरेक्शनल लिंक के बिना, हाइबरनेट ने कॉलम को पहले से सेट करने की कोशिश की। आप भी अपने में शामिल होने तालिका में शून्य मान देखने के लिए कि क्या होता है अगर आप द्विदिश रिश्ते

+0

के माध्यम से जाना होगा उत्तर .. मैंने कोशिश की, अब, जब मैंने सीआरयूडी (एडमिन) के माध्यम से किसी ग्राहक को हटाने की कोशिश की, तो मुझे यह त्रुटि मिली: त्रुटि ~ एक दावा विफलता हुई (यह हाइबरनेट में एक बग इंगित कर सकता है, लेकिन असुरक्षित होने की संभावना अधिक है सत्र का उपयोग) org.hibernate.AssertionFailure: संग्रह स्वामी सत्र से संबद्ध नहीं है: models.Order.cartItems –

+0

यहां [stacktrace] [1] [1]: http: //pastebin.com/r42mPEdB –

+0

है प्रश्न में कोड को अपडेट किया गया (अंत की ओर) –

0

जेपीए के झरना गुणों के साथ कोई समस्या है सक्षम करने के लिए नहीं करना चाहते हैं अनुमति देने का प्रयास कर सकते हैं। हाइबरनेट से संबंधित कैस्केड एनोटेशन का उपयोग करने का प्रयास करें और जेपीए से उपयोग किए गए सभी कैस्केड को हटा दें। यहां आपके पेम विधि मॉडल वर्ग का एक उदाहरण दिया गया है:

// Be careful, import the realted annotations from hibernate (not JPA) 
import org.hibernate.annotations.OnDelete; 
import org.hibernate.annotations.OnDeleteAction; 

@Entity 
public class PayMethod extends Model { 
    @Required 
    public String cardNumber; 

    @ManyToOne 
    @OnDelete(action = OnDeleteAction.CASCADE) 
    public Customer customer; 
    ... 
} 

उपरोक्त विधि यूनी-दिशात्मक मैपिंग के साथ मेरे लिए काम करता है। मुझे उम्मीद है कि यह आपकी समस्या का समाधान करेगा।

0

मैं एक ऐसी ही समस्या थी, लेकिन मैं एक सूची का उपयोग नहीं किया गया था, मैं एक संस्थाओं की सरणी का उपयोग कर रहा था।

मेरी रैपिंग इकाई के साथ समस्या यह थी कि उसने सरणी (नई MyEntity [0]) शुरू नहीं की क्योंकि मैं आमतौर पर अपनी सूचियों (नई ArrayList (0)) के साथ करता हूं।

मुझे एहसास हुआ (अनुभवजन्य विधि) कि "ऑल-डिलीट-अनाथ" रिश्ते से जुड़े "शून्य" सरणी को "मर्ज" करने का प्रयास करते समय, "org.hibernate.AssertionFailure: संग्रह स्वामी सत्र से संबद्ध नहीं है : "उठ गया।

तो मेरा सलाह का टुकड़ा यह है कि: "ऑल-डिलीट-अनाथ" रिलेशनशिप का उपयोग करते समय, अपने संग्रह (सरणी शामिल) को खाली उदाहरण के साथ प्रारंभ करें।

संबंधित मुद्दे