2017-05-04 13 views
0

나는 이와 같은 코드를 가지고있다. 내가 아는 레거시 코드가 아마도 최고의 코드는 아닙니다. 또한 우리는Hibernate getNamedQuery는 다른 UPDATE TABLE을 실행한다.

@org.hibernate.annotations.DynamicUpdate(value=true) 
@org.hibernate.annotations.SelectBeforeUpdate(value=true) 

모두를 사용하는

final Student student = loadStudentById(13); 
student.setLastAccessedTime(new Date()); 
student.setNote(20); 
updateWithHQLUsingNamedQueries(student);//HERE WE UPDATE BOTH FIELDS USING NAMEDQUERIES 

private void updateWithHQLUsingNamedQueries(final Student student){ 
    final Query query = session.getNamedQuery("namedQuery"); 
    query.setParameter("lastAccessedTime",student.getLastAccessedTime()); 
    query.setParameter("note",student.getNote()); 
    query.setParameter("c01",c01Field); 
    query.executeUpdate();//HERE HIBERNATE UPDATE THE STUDENT LIKE session.update(student); 
} 

확인을 작동하지만 SQL 로깅에 난 두 개의 업데이트이 같은 정기적 인 업데이트를 같은 첫째을 볼 수 있습니다.

update com.models.Student HIBERNATE MESSAGE 
update student set lastAccessedTime=:time and note=:note where id=:id 

그리고 나중에 내가 namedQueries

update student set c01=:c01 and lastAccessedTime=:time and note=:note where id=:id 

내 질문은의 업데이트를 참조 하이버 네이트 UPDATE?

Hibernate가 정기적 인 업데이트에서 Student 필드를 커밋하는 이유는 executeUpdate 바로 이전과 같은 일을하는 것입니까? 학생은 어디에도 저 지르지 않습니다.

session.update(student); 

나는 내가 DynamicTrue을 사용하고 어쩌면 마지막 업데이트 (NamedQuery)을 낭비 것 때문에 그들은 단지 더러운 필드를 업데이트하는 것을 알고있다. 하지만 Hibernate가 정기적 인 업데이트와 같이 학생 객체를 커밋하는 이유는 무엇입니까 ??? 두 가지 결과가 나왔습니까? 성능 저하?

덕분에 당신의 대답을 @coladit합니다하지만 난 수정하면 내 코드는 속성이 DB에 지속 할 플러시 않습니다이

final Student student = loadStudentById(13); 
student.setLastAccessedTime(new Date()); 
student.setNote(20); 
student.setAnotherProperty(value);//THIS CHANGE IS PERSISTED IN DB 

같은 다른 속성을 설정 ????? 속성을 수정하고 namedQuery가 지속되지 않아도 DB에 업데이트됩니다.

답변

1

트랜잭션에있는 경우 실제로 변경 내용을 적용하지 않습니다 (Student). 단지 데이터베이스에 플러시합니다. Query 개체에서 executeUpdate을 호출하면 데이터 일관성을 보장하기 위해 쿼리를 실행하기 전에 보류중인 모든 변경 내용이 플러시됩니다.

귀하의 loadStudentById은 Hibernate가 추적하는 관리 대상 엔티티를 반환합니다. 그것은 원래 상태의 복사본을 유지하고 모든 플러시시 오브젝트의 현재 상태와 비교합니다. 변경 사항을 추적하지 않으려면 session.detach(student) (EntityManager 인터페이스와 병합 된 Hibernate 5.2를 사용하는 경우)를 호출 할 수 있습니다.

+0

내 편집 된 질문을 참조하십시오. – chiperortiz

+0

제가 말했던 것처럼 관리 대상을 변경 했으므로 한 번 업데이트됩니다. 그리고 두 번째는 실행중인 수동 쿼리입니다. Flush는 모든 변경을'@Column (updatable = false) '또는 자식 엔티티에 해당하는 Cascade 옵션이없는 DB 필드로 보낸다. 원하는 경우 엔터티에 새 속성을 설정하고'session.flush() '를 호출하여 데이터베이스에서 업데이트 할 수 있습니다. – coladict

+0

감사합니다 pal 좋은 대답 – chiperortiz