सेशन के बीच अंतर क्या है। Merge और session.SaveOrUpdate


86

मैं अपने माता-पिता / बच्चे की वस्तुओं या कई-से-कई रिश्तों के साथ कभी-कभी नोटिस करता हूं, मुझे SaveOrUpdateया तो कॉल करने की आवश्यकता है या Merge। आमतौर पर, जब मुझे कॉल करने की आवश्यकता होती है, तो मुझे कॉल SaveOrUpdateकरने पर जो अपवाद मिलता है, वह Mergeक्षणिक वस्तुओं के साथ करना होता है, जो पहले सहेजे नहीं जाते।

कृपया दोनों के बीच अंतर स्पष्ट करें।

जवाबों:


157

यह धारा 10.7 से है। हाइबरनेट संदर्भ प्रलेखन की स्वचालित स्थिति का पता लगाना :

saveOrUpdate () निम्न कार्य करता है:

  • यदि वस्तु इस सत्र में पहले से ही स्थिर है, तो कुछ भी न करें
  • यदि सत्र से जुड़ी किसी अन्य ऑब्जेक्ट में समान पहचानकर्ता है, तो अपवाद को फेंक दें
  • यदि ऑब्जेक्ट में कोई पहचानकर्ता गुण नहीं है, तो इसे सहेजें ()
  • यदि ऑब्जेक्ट के पहचानकर्ता के पास एक नए तात्कालिक ऑब्जेक्ट को सौंपा गया मूल्य है, तो इसे सहेजें ()
  • यदि ऑब्जेक्ट संस्करणित किया जाता है (एक <संस्करण> या <टाइमस्टैम्प> द्वारा), और संस्करण संपत्ति का मूल्य एक ही तात्कालिक वस्तु को सौंपा गया मूल्य है, तो इसे सहेजें ()
  • अन्यथा अद्यतन () वस्तु

और मर्ज () बहुत अलग है:

  • यदि वर्तमान में सत्र के साथ समान पहचानकर्ता के साथ एक स्थायी उदाहरण है, तो दिए गए ऑब्जेक्ट की स्थिति को लगातार उदाहरण पर कॉपी करें
  • यदि वर्तमान में सत्र के साथ कोई स्थायी उदाहरण नहीं है, तो इसे डेटाबेस से लोड करने का प्रयास करें, या एक नया लगातार उदाहरण बनाएं
  • लगातार उदाहरण लौटाया जाता है
  • दिए गए उदाहरण सत्र से संबद्ध नहीं हो जाते हैं, यह अलग रहता है

यदि आप सत्र से अलग किए गए एक बिंदु पर वस्तुओं को अद्यतन करने का प्रयास कर रहे हैं, तो आपको मर्ज () का उपयोग करना चाहिए, खासकर यदि उन वस्तुओं के लगातार उदाहरण हो सकते हैं जो वर्तमान में सत्र से जुड़े हैं। अन्यथा, उस स्थिति में SaveOrUpdate () का उपयोग करने से अपवाद होगा।


अच्छा जवाब ... मुझे आश्चर्य है कि - अगर मैं किसी नई इकाई में मर्ज का उपयोग करता हूं तो इसके बाद सेव करने के लिए उपयोग करने का कोई कारण है या मैं यह मान सकता हूं कि मर्ज ने सुनिश्चित करने के लिए डीबी में नई इकाई बनाई है? (और अगर यह एक अलग इकाई है, तो एक बार विलय डीबी में स्वचालित रूप से छोड़ दिया जाता है?)
दानी

5
क्या तुम इसके बारे में निश्चित हो? NHiberante source को देखते हुए SaveOrUpdateCopy मर्ज फ़ंक्शन के समान पैरामीटर के साथ एक मर्ज इवेंट को ट्रिगर करता है। मुझे लगता है कि वे समान हैं, SaveOrUpdateCopy फ़ंक्शन कुछ ऐसा है जो 1.0 मेगाहर्ट्ज फ़ंक्शन में हाइबरनेट / nhibernate में मौजूद है और नए java मानक (मुझे लगता है) के अनुरूप हाइबरनेट में जोड़ा गया था
Torkel

5
@ टोरेल - SaveOrUpdateCopyजैसा नहीं है SaveOrUpdate। मुझे यकीन नहीं है कि प्रश्नकर्ता Mergeपूर्व या उत्तरार्द्ध की तुलना करना चाहता था । SaveOrUpdateCopyएक अब-अप्रचलित विधि है जिसे Mergeआयात किए जाने से पहले NHibernate में मर्ज किया गया था ।
कोडकाइजन

जानकर अच्छा लगा ... SaveOrUpdate अभी भी ट्यूटोरियल में बहुत अधिक उपयोग किया जाता है।
अनाल

9

मैं यह समझ के रूप में, merge()एक वस्तु है कि मौजूदा सत्र के साथ संबद्ध नहीं किया जा सकता ले जाएगा, और एक वस्तु है कि करने के लिए अपने राज्य (संपत्ति मूल्यों, आदि) की नकल कर रहा है (एक ही पी मूल्य / पहचानकर्ता के साथ, के चालू सत्र के साथ जुड़े पाठ्यक्रम)।

saveOrUpdate()किसी दिए गए ऑब्जेक्ट के पहचान मूल्य के आधार पर, आपके सत्र में सेव या अपडेट को कॉल करेगा ।


4

SaveOrUpdateCopy()अब NHibernate 3.1 के रूप में पदावनत किया गया है। Merge()इसके बजाय उपयोग किया जाना चाहिए।


9
यह SaveOrUpdateCopyचिह्नित है Obsolete, नहीं SaveOrUpdate। इस प्रश्न और बाद के उत्तर में इन दो अलग-अलग तरीकों के बीच बहुत भ्रम की स्थिति दिखाई देती है।
कोडकाइजन

2
** Update()**

: - यदि आप सुनिश्चित हैं कि सत्र में समान पहचानकर्ता के साथ पहले से ही लगातार उदाहरण नहीं है तो हाइबरनेट में डेटा को बचाने के लिए अपडेट का उपयोग करें

** Merge()**

: -यदि आप किसी सत्र की स्थिति के बारे में जानकर किसी भी समय अपने संशोधनों को बचाना चाहते हैं तो हाइबरनेट में मर्ज () का उपयोग करें।


1

मुझे यह लिंक मिला जिसने इस प्रकार के अपवाद की व्याख्या करते हुए बहुत अच्छा काम किया:

मेरे लिए क्या काम निम्नलिखित है:

  1. मैपिंग में Myclass.hbm.xml फ़ाइल, सेट करें cascade="merge"
  2. SaveOrUpdate बच्चे / आश्रित वस्तु को पहले मूल वस्तु को सौंपने से पहले।
  3. SaveOrUpdate मूल वस्तु।

हालाँकि, इस समाधान की सीमाएँ हैं। यानी, आपको हाइबरनेट करने के बजाय अपने बच्चे / आश्रित वस्तु को बचाने का ध्यान रखना होगा।

अगर किसी के पास बेहतर समाधान है, तो मैं देखना चाहता हूं।


-2
@Entity
@Table(name="emp")
public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="emp_id")
    private int id;
    @Column(name="emp_name")
    private String name;
    @Column(name="salary")
    private int Salary;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSalary() {
        return Salary;
    }

    public void setSalary(int salary) {
        this.Salary = salary;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

public enum HibernateUtil {
    INSTANCE;
    HibernateUtil(){
        buildSessionFactory();
    }
    private SessionFactory sessionFactory=null;

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    private  void buildSessionFactory() {
        Configuration configuration = new Configuration();

        configuration.addAnnotatedClass (TestRefresh_Merge.Employee.class);
        configuration.setProperty("connection.driver_class","com.mysql.jdbc.Driver");
        configuration.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/hibernate");                                
        configuration.setProperty("hibernate.connection.username", "root");     
        configuration.setProperty("hibernate.connection.password", "root");
        configuration.setProperty("dialect", "org.hibernate.dialect.MySQLDialect");
        configuration.setProperty("hibernate.hbm2ddl.auto", "update");
        configuration.setProperty("hibernate.show_sql", "true");
        configuration.setProperty(" hibernate.connection.pool_size", "10");
        /* configuration.setProperty(" hibernate.cache.use_second_level_cache", "true");
         configuration.setProperty(" hibernate.cache.use_query_cache", "true");
         configuration.setProperty(" cache.provider_class", "org.hibernate.cache.EhCacheProvider");
         configuration.setProperty("hibernate.cache.region.factory_class" ,"org.hibernate.cache.ehcache.EhCacheRegionFactory");
        */
        // configuration
        StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
           sessionFactory = configuration.buildSessionFactory(builder.build());
           setSessionFactory(sessionFactory);
    }

    public  static SessionFactory getSessionFactoryInstance(){
        return INSTANCE.getSessionFactory();
    }
} 


public class Main {
    public static void main(String[] args) {
        HibernateUtil util=HibernateUtil.INSTANCE;
        SessionFactory factory=util.getSessionFactory();
        //save(factory); 
        retrieve(factory);
    }

     private static void retrieve(SessionFactory factory) {
        Session sessionOne=factory.openSession();

        Employee employee=(Employee)sessionOne.get(Employee.class, 5);

        sessionOne.close(); // detached Entity

        employee.setName("Deepak1");

        Session sessionTwo=factory.openSession();

        Employee employee1=(Employee)sessionTwo.get(Employee.class, 5);
        sessionTwo.beginTransaction();
        sessionTwo.saveOrUpdate(employee); // it will throw exception

        //sessionTwo.merge(employee); // it will work

        sessionTwo.getTransaction().commit();

        sessionTwo.close();

    }

    private static void save(SessionFactory factory) {
        Session sessionOne=factory.openSession();
        Employee emp=new Employee();
        emp.setName("Abhi");
        emp.setSalary(10000);
        sessionOne.beginTransaction();
        try{

            sessionOne.save(emp);
            sessionOne.getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            sessionOne.close();
        }

    }
}

2
आपको अपने उत्तर को उस कोड को दिखाने पर विचार करना चाहिए जो प्रभावी है और फिर अंत में पूर्ण कोड डंप पर विचार करें। जैसा कि यह खड़ा है हमें टिप्पणियों में नीचे स्क्रॉल करना होगा और मौका देना होगा। देखें कैसे जवाब दें
कीड़े
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.