2011-11-23 5 views
1

Grails에서 이상한 것을 발견했습니다. 내가 방법을 전화 예를 들어, 그 이후grails를 저장하지 않고 DB에 삽입하는 이유는 무엇입니까?

User a = new User() 
a.setName("test") 
a.save() 

:

내가 좋아하는 객체를 생성 좋아 setActive :

a.setActive(true) 

()는 저장하지 전화를 DO 있지만 데이터베이스에 저장됩니다. 나는 이유를 모른다. 나는 이것이 위험하다고 생각한다. 이것에 대한 제안? 이 세션을 닫기 전에 최대 절전 모드가 자동으로 영구 객체에 대한 모든 보류중인 업데이트를 저장하기 때문에

고마워,

마르코

답변

3

서비스 메소드 실행 후 (transactional = true 인 경우) grails는 모든 변경 사항을 domain/persist 객체로 저장하고 최대 절전 모드 세션을 플러시합니다.
컨트롤러 동작의 리디렉션과 동일한 동작입니다.
변경 사항을 롤백하려면 RuntimeException을 throw하십시오.

2

. 이것은 Hibernate가 작동하는 방식이다.

.save()을 호출하여 객체를 영속화하려는 경우, Hibernate는 해당 객체에 대한 후속 변경 사항을 저장하기를 원한다고 가정합니다. 업데이트를 유지하지 않으려면 a.setActive(true)으로 전화를 걸어야합니다.

6

Grails는 각 요청의 시작 부분에서 최대 절전 모드 세션을 열고 "완료 후 그것을 플러시하고 닫는"OpenSessionInView 인터셉터를 등록합니다. 이것은 주로 lazy-loaded 컬렉션을위한 것이다. 열린 세션이 없으면 인스턴스를로드 한 후 즉시 연결이 끊어 지므로 컬렉션에 액세스하려고하면 예외가 발생합니다. 세션을 활성 상태로 유지하면 콜렉션을 확인할 수 있습니다.

기본적으로 Hibernate는 플러시 중에 영구 인스턴스의 변경 사항을 자동으로 푸시하므로 요청이 끝날 때 OSIV 인터셉터가 플러시되므로 사용자 인스턴스와 같은 "더티"인스턴스의 변경 사항은 데이터베이스로 푸시됩니다.

이 문제를 해결하려면 임시 인스턴스 만 수정하려는 경우 기존 인스턴스를로드하려면 read() 메서드를 사용할 수 있습니다. GSP에서 렌더링 할 수 있지만 변경 사항을 자동 지속하지 않으려는 경우

이전 인스턴스가 생성되지 않으므로 생성되지 않습니다. 귀하의 경우 저장 후 a.discard()으로 전화하면 Hibernate 세션과의 연결이 끊어지고 Hashnate는 플러시가 발생할 때 아무 것도 누르지 않습니다.

+0

하지만 discard()도 작동하지 않으면 어떻게됩니까? 여기에 제가하고있는 일이 있습니다 : 'contactInstance.discard() contactInstance.properties = params' 그러나 서비스 메소드를 실행 한 후 이러한 변경 사항은 save 메소드를 호출하지 않아도 데이터베이스에 반영됩니다 –

관련 문제