2014-12-14 10 views
0

TicketLine을 제거하려고하면 "삭제 된 객체가 계단식으로 다시 저장됩니다."문제가 발생합니다. Ticket 클래스에 속한 컬렉션의 개체는 Reservation 클래스와 OneToOne 연관을가집니다.org.hibernate.ObjectDeletedException : 컬렉션 객체가 일대일 관계를 가질 때 삭제 된 객체가 다시 저장됩니다.

class Reservation 
... 
@OneToOne() 
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN}) 
@JoinColumn(name = "resource_id") 
public TicketLine getTicketLine() { 
    return ticketLine; 
} 

을 티켓에 TicketLine 객체와 예약 객체에 추가 :

티켓은 다음과 같이

class Tickets 
... 
@OneToMany(targetEntity = TicketLine.class, fetch = FetchType.EAGER) 
@Fetch(org.hibernate.annotations.FetchMode.SUBSELECT) 
@Cascade({org.hibernate.annotations.CascadeType.ALL, 
    org.hibernate.annotations.CascadeType.LOCK, 
    org.hibernate.annotations.CascadeType.DELETE_ORPHAN,}) 
public List<TicketLine> getLines() { 
return ticketlines; 
} 
.... 

클래스 예약 TicketLines에 OneToOne 관계를 정의하는 다음 게터와 TicketLines의 컬렉션을 정의 TicketLine 객체와 함께

ticket.getLines().add(line); 
session.save(ticket); 

Reservation res = new Reservation(); 
res.setTicketLine(m_ticketline); 
.... 
session.save(res); 

예상대로 작동합니다. 예약 ID가 resource_id 필드 인 예약 레코드가 생성됩니다.

나는 다음과 같은 오류가 관련 예약 개체가 컬렉션에서 선을 제거하면 : 라인과 관련된 예약이있을 때

Save ticket failed: org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [org.myapp.hibernate.TicketLine#ff8081814a45ebb5014a45ebe4540003] 

에만이 오류가납니다. 흥미롭게도 새 세션에서 두 번째 시도가 예외를 throw하지 않지만 예약이 삭제되지 않습니다!

TicketLines 컬렉션에서 줄을 제거하는 것은 여러 위치에서 발생할 수 있습니다. 즉, 수동으로 예약을 제거하는 것은 실제로 옵션이 아닙니다. 이것이 Hibernate에 의해 관리 될 수 있기를 바란다. 그리고 나는 그냥 계단식 옵션에 문제가있다.

도와주세요.

+0

컬렉션에서 줄을 제거하는 코드로 게시물을 업데이트 할 수 있습니까? 또한 라인 오브젝트를 삭제하는 코드가 있습니까? –

+0

내 대답을 참조하십시오. 고맙습니다. – arcasys

답변

1

예외는 아래 코드와 함께 나타납니다. 그러나 문제는 예약 레코드가 있지만 line.getReservation()이 항상 null을 반환한다는 것입니다.

UPDATE

다음 mappedBy를 추가 예약에

@OneToOne(mappedBy="reservation") 

이 마지막 문제를 해결 때문이다. 이제 line.getReservation()도 작동합니다. 죄송합니다.

두 번째 업데이트 : 두 번째 수준 캐시가 유효한 한 이전에 제안 된 솔루션이 작동했습니다. 객체가 다시로드 된 후 NPE가 다시 발생했습니다. 관계를 소유하는 것에 관한 전문 용어를 파고 들자 마침내 다음과 같은 해결책을 찾았습니다.

클래스 티켓은 이전과 같이 TicketLines 컬렉션을 정의합니다.

class Reservation 
... 
privat TicketLine ticketline; 
... 
@OneToOne(fetch= FetchType.EAGER) 
@JoinColumn(name = "resource_id", insertable=false, updatable=false) 
public TicketLine getTicketline() { 
    return ticketline; 
} 
... 

어쩌면 내가 필드 RESOURCE_ID 명명 한 것을 설명 할 필요가 다음과 같이

class TicketLine 
... 
private reservation; 
... 

@OneToOne(mappedBy="ticketline", cascade= CascadeType.ALL, fetch= FetchType.EAGER) 
@JoinColumn(name="id", referencedColumnName="resource_id") 
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN}) 
public Reservation getReservation() { 
    return reservation; 
} 
... 

클래스 예약 TicketLines에 OneToOne 관계를 정의

클래스 TicketLine 지금과 같은 관계를 정의 향후 일대일 관계의 추가 유형에도 사용될 수 있습니다. 그러나 이것은 현재로서는 역할을해서는 안됩니다. 티켓에 TicketLine 객체와 현재 TicketLine 객체에 예약 객체를 추가

간다 :

ticket.getLines().add(line); 
session.save(ticket); 

Reservation res = new Reservation(); 
/* set property values */ 
/* line might not yet have an id at that pit of time, but we need one! */ 
sesssion.save(line); 
/* Instead of explicitly setting resource_id I tried to call 
    res.setTicketline(line); 
    but this will not set the resource_id as I expected 
*/ 
res.setResource_id(line.getId()); 
m_ticketline.setReservation(res); 
.... 
/* session.save(res); 
    res is now saved when the ticket containing the line will be saved later*/ 
.... 
session.save(ticket); 

선을 저장 및

ticket.getLines().remove(line); 
session.save(ticket); 

로 라인을 삭제하거나 모든 행을 삭제 (및 resarvations) 티켓과 함께 티켓과 함께

session.delete (티켓);

모두 예상대로 작동합니다.

많은 변경 사항에 대해 사과하지만이 문제는 해결하기가 어려워서 실제로 답변을 드리려고합니다.

감사합니다.