2012-01-13 2 views
9

내가 최대 절전 모드를 테스트하고최대 절전 모드

transaction = session.beginTransaction(); 
city = new City("A"); 
city = (City)session.merge(city); 
city.setName("B"); 
transaction.commit(); 

이 쿼리를주고 내가 명령 줄에서 그 쿼리를 얻고 있어요 병합 내 개체 업데이트, 그것은 업데이 트해서는 안됩니다. 맞지? 실수는 무엇입니까?

+1

이 링크가 유용 할 수있다 : 다음과 같이

Exception in thread "main" org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: This is because Hibernate is enforcing that only a single instance of a Persistent object exists in memory. 

상기 문제를 해결하기 위해, 병합()가 이용된다 http://stackoverflow.com/questions/ 161224/what-are-the-different-between-the-different-saving-methods in -hibernate – Gaurav

답변

22

좀 더 구체적인 예를 사용하여 설명하려고합니다. 다음과 같은 시나리오가 있다고 가정 해보십시오.

Session session = sessionFactory.openSession(); 
Transaction transaction = session.beginTransaction(); 
User userA = (User)session.get(User.class, 1101); 
transaction.commit(); 
session.close(); 
// Since session is closed, userA is detached. 

session = sessionFactory.openSession(); 
transaction = session.beginTransaction(); 
User userB = (User)session.get(User.class, 1101); 
//Now here, userB represents the same persistent row as userA. 
//When an attempt to reattach userA occurs, an exception is thrown 
session.update(userA); 
transaction.commit(); 
session.close(); 

예외 Detached 객체를 다시 연결하려고하면 userA가 생성됩니다.

Session session = sessionFactory.openSession(); 
Transaction transaction = session.beginTransaction(); 
User userA = (User)session.get(User.class, 1101); 
transaction.commit(); 
session.close(); 
//userA is now detached as session is closed. 

session = sessionFactory.openSession(); 
transaction = session.beginTransaction(); 
User userB = (User)session.get(User.class, 1101); 
User userC = (User)session.merge(userA); 
if (userB == userC) { 
    System.out.println("Reattched user is equal"); 
} 
transaction.commit(); 
session.close(); 
+0

session.update (p1)의 p1은 무엇입니까? 그것은 userA입니까? – Elbek

+0

각각의 '대화'(클라이언트 요청)'은 자체 'userA' 참조를 가질 수 있습니다, 그렇습니까? –

0

세션이 아직 닫히지 않았고 지속성 용어로 인해 city 개체가 여전히 세션에 연결되어 있기 때문입니다. 따라서 해당 객체의 모든 변경 사항은 최대 절전 세션에 의해 수신되고 적절한 dml 문이 호출됩니다.

+0

은 save() not merge()를 사용할 경우에 적합합니다. 병합에 여전히 적합한 경우 저장 및 병합의 차이점은 무엇입니까? – Elbek

+1

병합은 인스턴스를 분리 할 때 유용합니다. 위의 경우 세션을 닫을 때'city' 객체가 남아 있습니다. 세션을 닫은 후'city' 객체를 약간 변경한다고 가정 해보십시오. 이제 다시 세션을 열고 변경 사항이 유지되는지 확인하려고합니다. 이 경우 당신은 세션 객체로'merge'를 사용하고 최대 절전 모드는 변경 사항이 데이터베이스에 반영되도록 할 것입니다. 'save'는 주로 엔티티를 지속시키기 위해 사용되며 식별자를 돌려줍니다. – Gaurav

+0

이 경우에 u가 업데이트되었다고해도 update()를 사용하여 업데이트 할 수 있습니다. 필요는 내가 대답에 대한 포인트 덕분에있어 – Elbek

3

이것은 시퀀스 문제입니다. 실제로 문제는 아닙니다. Hibernate는 당신이 말한 것과 똑같이하고 있습니다. @TejasArjun이 말했듯이 병합은 deteched 데이터를 병합하는 것과 관련이 있습니다. 여기에 무슨 일이 일어나고 :

... 
city = (City)session.merge(city); 
// No different to save(). Hibernate schedules an insert to the 
// database to store the current record. 

city.setName("B"); 
// The object is now flagged as dirty and needing to be saved. 
// Hiberate automatically tracks properties on objects and knows when they change. 

transaction.commit(); 
// Hibernate sees that 'city' has been changed since it was saved, 
// so it schedules an update to store the new data. 
+0

:() (병합을 사용하지 않는 것이 아니라 심지어 나는이 방법으로 위의에 도달 할 수 있습니다 : \t \t city.setName ("Q"); \t \t \t \t \t \t 세션 . = HibernateUtil.getSessionFactory()과() OpenSession에(); \t \t 거래 = session.beginTransaction(); \t \t \t \t session.update (도시) \t \t \t \t transaction.commit(); 왜 병합() 메소드가 필요합니까? 동일 함 – Elbek

+0

두 번째 대답에서 병합 사용에 대한 예제를 참조하십시오. – Gaurav