親/子オブジェクトまたは多対多の関係で、SaveOrUpdate
またはのいずれかを呼び出す必要があることに気付くことがありますMerge
。通常、を呼び出す必要がある場合、呼び出すときにSaveOrUpdate
発生する例外は、Merge
最初に保存されていない一時オブジェクトに関係しています。
両者の違いを説明してください。
回答:
これはセクション10.7からです。Hibernateリファレンスドキュメントの自動状態検出:
saveOrUpdate()は次のことを行います。
- オブジェクトがこのセッションですでに永続的である場合は、何もしません
- セッションに関連付けられている別のオブジェクトが同じ識別子を持っている場合は、例外をスローします
- オブジェクトに識別子プロパティがない場合は、save()
- オブジェクトの識別子に、新しくインスタンス化されたオブジェクトに割り当てられた値がある場合は、save()
- オブジェクトが(<version>または<timestamp>によって)バージョン管理されており、バージョンプロパティ値が新しくインスタンス化されたオブジェクトに割り当てられた値と同じである場合、save()
- それ以外の場合は、オブジェクトをupdate()します
そしてmerge()は非常に異なります:
- 現在セッションに関連付けられているのと同じ識別子を持つ永続インスタンスがある場合は、指定されたオブジェクトの状態を永続インスタンスにコピーします
- 現在セッションに関連付けられている永続インスタンスがない場合は、データベースからロードするか、新しい永続インスタンスを作成してみてください
- 永続インスタンスが返されます
- 指定されたインスタンスはセッションに関連付けられず、切り離されたままになります
ある時点でセッションから切り離されたオブジェクトを更新しようとしている場合、特に現在セッションに関連付けられているオブジェクトの永続インスタンスが存在する可能性がある場合は、Merge()を使用する必要があります。それ以外の場合、その場合にSaveOrUpdate()を使用すると、例外が発生します。
SaveOrUpdateCopy
同じではありませんSaveOrUpdate
。質問者Merge
が前者と後者のどちらを比較したいかはわかりません。SaveOrUpdateCopy
は、Merge
インポートされる前にNHibernateでマージを行った現在は廃止されたメソッドです。
私はそれを理解するように、merge()
現在のセッションに関連付けることがないかもしれないオブジェクトを取り、オブジェクトにその状態(等プロパティ値など)をコピーしているから、同じPK値/識別子(現在のセッションに関連付けられていますコース)。
saveOrUpdate()
指定されたオブジェクトのID値に基づいて、セッションで保存または更新を呼び出します。
SaveOrUpdateCopy()
NHibernate3.1で非推奨になりました。Merge()
代わりに使用する必要があります。
SaveOrUpdateCopy
とマークされているObsolete
、ではありませんSaveOrUpdate
。この質問とその後の回答では、これら2つの異なる方法の間に多くの混乱があるようです。
** Update()**
:-セッションに同じ識別子を持つ既に永続的なインスタンスが含まれていないことが確実な場合は、updateを使用してデータを休止状態で保存します
** Merge()**
:-セッションの状態を知らずにいつでも変更を保存したい場合は、hibernateでmerge()を使用してください。
@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();
}
}
}