나는 여기에 손실이 있으며, 아마도 Hibernate 전문 지식이 다른 영역보다 약하기 때문에 아마도 명백한 것이다.Hibernate가 기존 데이터를 마이 그 레이션하기위한 임베드 가능 클래스를 스왑 아웃
레거시 코드에는 최대 절전 모드 @Entity
클래스 Foo
이 있습니다.
@Embeddable
public class OldBar {
private String fooBar;
@Column(length = 10, nullable = false)
private String getFooBar() {
return fooBar;
}
@SuppressWarnings("unused")
private void setFooBar(String fooBar) {
this.fooBar = fooBar;
}
}
원래 문제는 내가 OldBar.fooBar
뭔가를 할 필요가 있다는 것입니다,하지만 :
private OldBar bar = new OldBar();
OldBar
가 단일 열, foobar
를 사용하는 @Embeddable
클래스 다음 속성 중 하나는 이것이다 독창적 인 디자인에는 제한이 있었고이 필드를 비공개로 설정하여 하위 클래스 화를 막았습니다. 따라서 다른 클래스 (NewBar
)를 만들어야만 다른 필드를 액세스하고 비공개 필드에 액세스 할 수있었습니다.
private NewBar bar = new NewBar();
나는 내가 foobar
열에서 기존 데이터를 가지고 있기 때문에이 일을 원했고, : 나는 NewBar
도 Embeddable
과 같은 @Column
지정을 가지고 있기 때문에, 내가 클래스 Foo
의 필드를 교체 단지 수 있다고 생각 OldBar
대신 NewBar
으로이 데이터를 투명하게 사용하고 싶습니다.
추적 로그를 통해 나는 의 기본 버전으로 생성자가 호출 될 때 예상대로 Foo()
이 생성 된 것을 확인했습니다. 그러나 시간 코드 Foo.getBar()
을 호출하면 어떤 이유로 bar
은 null
입니다! 나는 Hibernate가 어떤 이유에서 이것을 null
으로 설정하고 있다고 가정한다. 그러나 최대 절전 모드가 foobar
컬럼에서 데이터를 읽고 NewBar
의 인스턴스를 생성하는 이유는 무엇인가? OldBar
을 NewBar
대신 넣으면 다시 작동하는 이유는 무엇입니까? 확실히 @Embeddable
클래스 중 어떤 클래스가 열에 매핑되는지는 데이터베이스 자체에 아무것도 없습니다.
업데이트 : 이것은 낯선 사람과 낯선 사람을 얻습니다. 때로는 코드를 밤새 사용하게하고 그 다음날 작동합니다! 아니면 다음 날에 작동하지 않습니다! 지금은 작동하지 않습니다 (즉, foobar
속성은 데이터베이스의 값 대신 null
으로 설정 됨), 따라서 ExactCopyOfOldBar
클래스를 만들어 OldBar
대신 넣었습니다. 괜찮 았어! 따라서 NewBar
으로 다시 전환합니다. 일시적인 변경 사항을 취소하기 만하면됩니다. 전에는 없었던 때에도 여전히 효과가있었습니다! Hibernate가 값을 직렬화하고 데이터베이스에서 가져 오지 않는 일종의 캐시가 있습니까? 이것은 매우 이상합니다.
업데이트 : 이제 더 이상 NewBar
을 사용할 수 없습니다. OtherBar
을 만듭니다.이 이름은 기본적으로 NewBar
과 동일합니다. 단, 이름이 다르며 플러그를 꽂으면 올바르게 작동합니다. 포함 된 문자열을 올바르게 읽습니다. 다시 NewBar
으로 전환하면 null
이 다시 발생합니다. 무슨 일 이니?
Foo
은 아주 간단하다,
net.databinder.auth.hib.AuthDataApplication.getUser(String username)
통해로드되고 있음을
참고 : 나는 Foo
(사용자) 테이블이 올바른 데이터를 단일 행을 가지고 또 다시 확인하고 한
return (DataUser) Databinder.getHibernateSession().createCriteria(getUserClass())
.add(Restrictions.eq("username", username)).uniqueResult();
및 가장 중요한 것은 foobar
필드에 데이터가 있다는 것입니다. 왜 Hibernate는 null
foobar
필드를 가지고 Foo
을 돌려 주나요? NewBar
에서 OtherBar
으로 간단히 전환하면 다시 작동하기 시작하는 이유는 무엇입니까? 내가 하루 종일 방치 한 후 하루 종일 작동하고 일을 멈추는 이유는 무엇입니까?
나는 이것이 사실 있으리라 믿고있어,하지만 당신은 그것을 말하지 않았다 : Foo.bar'는'@ Embedded'로 표시'있습니까? –
@Tim Pote : 사실 이상하게도 원래의 (작동중인) 레거시 코드에서는'@ Embedded'라고 표시되지 않았습니다. 'OldBar'를'NewBar'로 변경했을 때'@ Embedded'의 유무에 관계없이 시도해 보았지만 차이는 없었습니다. –
@ 팀 Pote : 나는 ... 최대 절전 모드 [문서] (http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/) "그에서 배운 경우, 재산의 종류 @Embeddable로 주석 처리되고, @Embedded로 매핑됩니다. "기술적으로'@ Embedded' 부분은 선택 사항입니다. –