Quelle est la différence entre session.Merge et session.SaveOrUpdate?

Je remarque parfois avec mes objects parent / enfant ou des relations plusieurs-à-plusieurs, je dois appeler soit SaveOrUpdate ou Merge . Habituellement, lorsque j’ai besoin d’appeler SaveOrUpdate , l’exception que j’obtiens lors de l’appel de Merge concerne les objects transitoires qui ne sont pas enregistrés en premier.

Veuillez expliquer la différence entre les deux.

    Ceci est de la section 10.7. Détection automatique de l’état de la documentation de référence Hibernate:

    saveOrUpdate () effectue les opérations suivantes:

    • si l’object est déjà persistant dans cette session, ne faites rien
    • si un autre object associé à la session a le même identifiant, lancez une exception
    • Si l’object n’a pas de propriété d’identifiant, enregistrez-le ()
    • si l’identifiant de l’object a la valeur assignée à un object nouvellement instancié, enregistrez-le ()
    • Si l’object est versionné (par une version ou ) et que la valeur de la propriété version est la même valeur que celle atsortingbuée à un object nouvellement instancié, enregistrez-le
    • sinon mettre à jour l’object

    et fusionner () est très différent:

    • s’il y a une instance persistante avec le même identifiant actuellement associé à la session, copiez l’état de l’object donné sur l’instance persistante
    • si aucune instance persistante n’est actuellement associée à la session, essayez de la charger à partir de la firebase database ou créez une nouvelle instance persistante
    • l’instance persistante est renvoyée
    • l’instance donnée n’est pas associée à la session, elle rest détachée

    Vous devez utiliser Merge () si vous essayez de mettre à jour des objects qui ont été détachés de la session, en particulier s’il existe des instances persistantes des objects actuellement associés à la session. Sinon, l’utilisation de SaveOrUpdate () dans ce cas entraînerait une exception.

    Si je comprends bien, merge() prendra un object qui ne sera peut-être pas associé à la session en cours et copiera son état (valeurs de propriété, etc.) sur un object associé à la session en cours (avec la même valeur PK / identifiant, bien sûr).

    saveOrUpdate() appelle Save ou Update sur votre session, en fonction de la valeur d’identité d’un object donné.

    SaveOrUpdateCopy() est maintenant obsolète à partir de NHibernate 3.1. Merge() doit être utilisé à la place.

    J’ai trouvé ce lien qui a très bien expliqué ce type d’exception:

    Ce qui a fonctionné pour moi est le suivant:

    1. Dans le fichier de mappage Myclass.hbm.xml, définissez cascade="merge"
    2. SaveOrUpdate l’object enfant / dépendant en premier avant de l’atsortingbuer à l’object parent.
    3. SaveOrUpdate l’object parent.

    Cependant, cette solution a ses limites. C’est-à-dire que vous devez prendre soin de sauver votre enfant / object dépendant au lieu de le laisser faire pour vous.

    Si quelqu’un a une meilleure solution, j’aimerais voir.

    Nouvel identifiant d’utilisateur, donc je ne peux pas commenter ou voter sur le post de Quoc Truong. Cependant, je pense également que le lien est très utile, comme indiqué précédemment.

    http://www.roseindia.net/hibernate/hibernate4/org_hibernate_nonuniqueobjectexception.shtml

     ** Update()** 

    : – si vous êtes sûr que la session ne contient pas une instance déjà persistante avec le même identifiant, utilisez la mise à jour pour enregistrer les données en veille prolongée

     ** Merge()** 

    : -si vous voulez sauvegarder vos modifications à tout moment sans connaître l’état d’une session, utilisez merge () dans hibernate.

     @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 Ssortingng name; @Column(name="salary") private int Salary; public Ssortingng getName() { return name; } public void setName(Ssortingng 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(Ssortingng[] args) { HibernateUtil util=HibernateUtil.INSTANCE; SessionFactory factory=util.getSessionFactory(); //save(factory); resortingeve(factory); } private static void resortingeve(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(); } } }