2012-04-07 5 views
2

1 : 1 매핑을 갖는 2 개의 엔티티 플러그와 소켓이 있습니다.Hibernate와 일대일 관계를 변화시키는 관계를 모델링하는 방법

이제 플러그에는 연결된 소켓과 외래 키 관계가 있습니다.

Hibernate는 일대일 매픽을 보장하기 위해 외래 키에 대한 고유 제한 조건을 생성합니다.

10 개의 플러그가 10 개의 소켓에 꽂혀 있습니다.

시간이 지나면 시스템에 변경 사항이 있음을 알리는 업데이트가 제공됩니다.

socketA에 연결되었던 plugA가 이제 SocketB에 연결되고 SocketB에 연결되었던 plugB가 socketA에 연결됩니다.

업데이트를 수행 할 때, 최대 절전 모드는 플러그 인의 외부 키 열을 SocketB로 업데이트하여 고유 제한 조건을 위반하려고합니다. 이것은 socketB와 plugB의 관계가 아직 변경되지 않았기 때문입니다.

관계를 모델링하는 가장 정확한 방법은 무엇입니까?

전체 업데이트는 단일 트랜잭션으로 발생해야합니다.

이 코드

내부 소켓

@OneToOne(mappedBy="socket") 
public Plug getPlug() 
{ 
    return plug; 
} 

내부 플러그 @OneToOne (옵션 = false)를 공공 소켓 getSocket() { 반환 소켓입니다; }

+0

왜 그렇게 많은 일을하지 않습니까? 소켓을위한 많은 플러그 – kommradHomer

답변

0

은 내가 당신을 제안하거나 내가 시도하고 그것을 해결했다 그래서 질문을 좋아

first transction : 
set both plug.socket to null 

second transaction: 
set both plug.socket to what you eventually want 

또는

사용 many-to-one

+0

@kommradHommer 팁 주셔서 감사합니다. –

+0

당신이 묘사하는 것은 지금 당장 나를위한 접근법입니다. 그러나 위반으로 인해 두 번째 거래가 실패하면 어떻게됩니까? Hibernate에서 가장 중요한 트랜잭션을 갖는 방법이 있습니까? 다시 초기 상태로 되돌릴 수 있습니까? –

0

추천 트랜잭션을 가지고있다.

@Override 
public void swap(Socket s1, Socket s2) { 
    s1 = em.find(Socket.class, s1.getId()); 
    s2 = em.find(Socket.class, s2.getId()); 
    Plug plug1 = s1.getPlug(); 
    Plug plug2 = s2.getPlug(); 
    plug1.setSocket(null); //This is to avoid duplicate key exception 
    plug2.setSocket(null); 
    em.flush(); //Without this the nullifying will just be overwritten by the next change. 
    plug1.setSocket(s2); 
    plug2.setSocket(s1); 

} 

지금이와 소켓 필드는 중요하다 그 것을 : 그래서

그래서 당신이해야 할 일이 같은 것입니다 : ... 당신이 당신의 자신에 그것을 알아 냈 아직하지 않은 희망 nullable/optional. 따라서 optional=true을 삭제해야합니다. 그러나 그것은 그래서 당신이 할 것은 이것이다 .. 관계가 효과적으로 많은에 하나가 같은 불일치로 이어질 수있는 고유 제한 조건없이 잎 :

@OneToOne 
@JoinColumn(nullable=true, unique=true) 
private Socket socket; 

그래서 남아있는 유일한 문제는 지금이 허용된다는 것입니다 소켓이없는 플러그를 지속시킵니다. 이것은 큰 문제가 아니어야 DAO에서 쉽게 예방/유효성 검사가 가능합니다.

관련 문제