2013-02-17 17 views
5

मैं एक इकाई वर्ग भुगतान जो इकाई वर्ग कई एक रिश्ते को साथ PAYMENTMETHOD है की है।@ManyToOne यूनिडायरेक्शनल मानचित्रण

अब मेरा भुगतान विधि मास्टर टेबल है।

तो मैं मास्टर टेबल PaymentMethod को प्रभावित किए बिना भुगतान को सहेजना चाहता हूं।

लेकिन हर बार जब मैं भुगतान को सहेजता हूं तो यह भुगतान विधि में नई पंक्ति डालता है। मैं समझने में असमर्थ क्यों हूं।

मैं स्प्रिंगडाटा सेव का उपयोग कर रहा हूं।

Payment.java

@Entity 
@Table(name="payment") 
public class Payment implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @ManyToOne(cascade={CascadeType.REFRESH,CascadeType.MERGE,CascadeType.PERSIST}) 
    @JoinColumn(name="payment_method_id") 
    private PaymentMethod paymentMethod; 

    //getter and setters 
} 

PaymentMethod.java

@Table(name="paymentmethod") 
public class PaymentMethod implements Serializable { 
@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
private Long id; 

@Column(name="name",unique=true ,nullable=false) 
private String name; 

//GETTER AND SETTERS 
} 

PAYMENT_METHOD आंकड़े

ID | NAME 
1 | AA 
2 | BB 
3 | CC 

भुगतान के बाद डुप्लिकेट नाम के साथ PAYMENT_METHOD प्रविष्टि को सहेजने के बाद?

मुझे पता लगाने में असमर्थ क्यों है?

बचत मैं भुगतान प्रकार

भंडार की इकाई को बचाने फोन करने के लिए सरल CRUDRepository बनाया है के लिए

कृपया सुझाव दें कि मैं कहां से बाहर निकल रहा हूं।

जब भी कोड इस लाइन को निष्पादित करता है:

paymentMethodRepository.findByName(payment.getPaymentMethod().getName()); 

यह त्रुटि

Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing: com.enrollment.domain.Payment.paymentMethod -> com.enrollment.domain.PaymentMethod 
    at org.hibernate.engine.spi.CascadingAction$8.noCascade(CascadingAction.java:380) 
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:176) 
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:423) 
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:264) 
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193) 
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:136) 
    at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78) 
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208) 
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151) 
    at org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:870) 
    at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:863) 
    at org.hibernate.engine.spi.CascadingAction$8.cascade(CascadingAction.java:346) 
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380) 
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323) 
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208) 
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:409) 
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:350) 
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326) 
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208) 
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165) 
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:448) 
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:293) 
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193) 
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:136) 
    at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78) 
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208) 
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151) 
    at org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:870) 
    at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:863) 
    at org.hibernate.engine.spi.CascadingAction$8.cascade(CascadingAction.java:346) 
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380) 
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323) 
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208) 
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165) 
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:448) 
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:293) 
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193) 
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:136) 
    at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78) 
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208) 
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151) 
    at org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:870) 
    at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:863) 
    at org.hibernate.engine.spi.CascadingAction$8.cascade(CascadingAction.java:346) 
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380) 
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323) 
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208) 
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165) 
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:423) 
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:264) 
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193) 
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:136) 
    at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78) 
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208) 
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151) 
    at org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:870) 
    at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:863) 
    at org.hibernate.engine.spi.CascadingAction$8.cascade(CascadingAction.java:346) 
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380) 
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323) 
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208) 
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165) 
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:423) 
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:264) 
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193) 
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:136) 
    at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78) 
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208) 
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151) 
    at org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:870) 
    at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:863) 
    at org.hibernate.engine.spi.CascadingAction$8.cascade(CascadingAction.java:346) 
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380) 
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323) 
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208) 
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:409) 
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:350) 
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326) 
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208) 
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:160) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:151) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88) 
    at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:58) 
    at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1186) 
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1241) 
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101) 
    at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:285) 

के रूप में मैं यह पता लगाने में असमर्थ हूँ देता है कि कैसे अगर यह फ्लश करने के लिए जब मैं रिपोजिटरी से खोजक विधि कॉल की कोशिश कर कोड।

क्या मुझे कुछ याद आ रहा है?

समस्या हल @JB और @spiritwalker, लेकिन सटीक मूल कारण खोजने में असमर्थ, इसलिए केवल व्यवहार पर चर्चा करने से चर्चा भी जानी जा सकती है।

Behaviour .. 

Open Transaction 
    1. validate 
    2. save child 
    3. validate and update 
    4. save parent 
Close Transaction 

it was giving above error. 

Now, after code change it worked 

Open Transaction 
    1. validate 
    2. validate and update 
    3. save child 
    4. save parent 
Close Transaction 
+1

समस्या यह है कि चरण 3 में, आप एक डेटाबेस क्वेरी को क्रियान्वित कर रहे हैं। इसलिए, इसे निष्पादित करने से पहले, हाइबरनेट अपने इन-मेमोरी परिवर्तनों को फ़्लश करता है यह सुनिश्चित करने के लिए कि क्वेरी स्मृति में संग्रहीत नए मान देख सकती है, लेकिन अभी तक डेटाबेस में संग्रहीत नहीं है। और चूंकि इन-मेमोरी स्थिति वैध नहीं है, इसलिए आपको यह अपवाद मिलता है। –

+0

सही, लेकिन चूंकि मैं अभी भी लेनदेन में हूं (readonly = false), इसलिए आपको नहीं लगता कि, चुनिंदा क्वेरी निष्पादित करने पर, फ्लश नहीं होना चाहिए। [नोट: मास्टर डेटा के लिए निष्पादित किया गया था]। –

+0

नहीं, मुझे ऐसा नहीं लगता है। मान लीजिए कि एक लेनदेन में, आप कई भुगतान कर रहे हैं, और उसके बाद उसी लेनदेन में, आप किसी दिए गए प्रकार के सभी भुगतानों को सूचीबद्ध करना चाहते हैं। आप निश्चित रूप से भुगतान में चाहते हैं जो आपने अभी परिणाम में शामिल किए हैं (जैसे कि आपने जेडीबीसी का उपयोग करके भुगतान डाला है)। यही कारण है कि सत्र फहराया गया है। –

उत्तर

2

आपके भुगतान संस्था से झरना = {CascadeType.REFRESH, CascadeType.MERGE, CascadeType.PERSIST} को हटा दें।

चूंकि भुगतान विधि एक मास्टर टेबल है जैसा आपने कहा था, आप भुगतान से भुगतान भुगतान विधि तक कोई कैस्केडिंग ऑपरेशन नहीं करना चाहते हैं।

+0

अगर मैं इसे हटा देता हूं तो अलग-अलग इकाई को सहेजने की कोशिश कर रहा है .. –

+0

आपको भुगतान विधि विधि उदाहरण पुनर्प्राप्त करने और भुगतान इकाई को असाइन करने की आवश्यकता है। – spiritwalker

+0

मैं वही –

3

कैस्केड को हटाकर प्रारंभ करें, क्योंकि जब आप भुगतान बनाते/संशोधित करते हैं तो आप भुगतान विधि को बनाना/संशोधित नहीं करना चाहते हैं।

फिर

, जब आप एक भुगतान बनाने के लिए, यह मौजूदा PAYMENTMETHOD आप चाहते हैं इसके साथ जुड़े होने के लिए आवंटित:

PaymentMethod existingPaymentMethod = em.find(PaymentMethod.class, idOfThePaymentMethod); 
Payment payment = new Payment(); 
payment.setPaymentMethod(existingPaymentMethod); 
em.persist(payment); 
+0

वसंत भंडार सहेजने की विधि देता है जो आंतरिक रूप से वही करता है यदि आईडी शून्य है –

+0

यदि शून्य की आईडी सही है? वसंत भंडार उन वस्तुओं को लेता है जिन्हें आप उसे देते हैं। यदि आप उसे एक मौजूदा भुगतान देने के बजाय उसे एक नया भुगतान विधि देते हैं, तो यह काम नहीं करेगा जैसा आप चाहते हैं। –

+0

आप सही करते हैं लेकिन सही ऑब्जेक्ट को सेट करने के बाद भी वैसे ही काम करते हैं। क्यों पता लगाने में असमर्थ? –

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