2012-11-28 1 views
8

기본 질문 : @ 임베드 된 객체가 항상 인스턴스화되지 않는 이유는 무엇입니까?기본 데이터 유형 필드가없는 @ 내장 객체는 자동으로 인스턴스화되지 않습니다.

재미있는 관찰은 기본 데이터 유형 (int, boolean ...)을 포함하지 않거나 전에 만진 적이 없다면 Ebean이 @Embedded 객체를 인스턴스화하지 않는다는 것입니다. 예 :

@Entity 
public class Embedder { 
    // getNotAutoInstantiated() will return null if this field was not touched before 
    @Embedded 
    private NotAutoInstantiated notAutoInstantiated = new NotAutoInstantiated(); 
    // getAutoInstantiated() will always return an instance! 
    @Embedded 
    private AutoInstantiated autoInstantiated = new AutoInstantiated(); 
} 

@Embeddable 
public class AutoInstantiated { 
    // theKey is why this embedded object is always instantiated 
    private int theKey; 
    private String field1;  
} 

@Embeddable 
public class NotAutoInstantiated { 
    private String field2;  
} 
+0

여러 내장 된 개체 간의 필드 이름 충돌 문제가 발생할 수 있습니다. 일반적으로 JPA 제공자는 임베디드 오브젝트 필드를 상위 테이블의 컬럼에 맵핑합니다. 포함 된 필드 이름이 길면 데이터베이스에서 잘린 필드 이름이 생겨 결국 열 이름의 충돌로 끝날 수 있습니다. – Zagrev

+0

예는 속일 수 있습니다. 이름은 내 코드에서 훨씬 짧으며 같은 접두어로 시작하지 않습니다. 그러나 예제에서조차 필드는 "not"와 "auto"로 시작하기 때문에 절사가 큰 문제는 아닙니다. – allprog

+0

사실 "필드"와 "필드"에 대해 생각하고있었습니다. – Zagrev

답변

3

나는 JPA 스펙이 명확하게 @Embedded 객체의 속성이 모든 널 (null)을 때 어떻게해야하는지에 대해 설명 생각하지 않지만, 적어도 일부 구현은 null 객체로 null의 특성을 가진 개체를 치료하는 당신이보고있는 것입니다.

이것은 합리적인 구현처럼 보입니다. 확실히 내 코드 (Hibernate 사용)에서 유용하다. 만약 내가 @Embedded 객체를 null로 설정했다면, 영속 버전을로드 할 때 null을 남기고 싶을 것이다.

예를 들어 theKey은 null이 될 수 없으므로 AutoInstantiated 클래스는 null로 간주 될 수 없습니다.

+0

불행히도 그 상황은 그보다 더 나쁩니다. Ebean은이 행동과 일치하지 않는 것으로 보입니다. AutoInstantiated와 같은 @Embedded 필드가 실제로 대부분의 장소에서 자동으로 인스턴스화되는 꽤 복잡한 데이터 모델이 있습니다. 그러나 이것이 일어나지 않는 곳이 한 곳 있습니다.우리는 그 특이성을 찾을 수 없었습니다. 다른 null 검사가 필요하므로 "null로 남겨두고"접근하는 것이 나에게 가장 적합하지 않습니다. 이것은 Java에서 최악의 관행입니다. 그런 경우에 쉽게 피할 수 있습니다 ... – allprog

3

당신은 확인 할 수 있습니다 : 5.1 이후 특히

https://hibernate.atlassian.net/browse/HHH-7610

을 :

static final String CREATE_EMPTY_COMPOSITES_ENABLED 

Enable instantiation of composite/embedded objects when all of its 
attribute values are null. The default (and historical) behavior is that a null reference 
will be used to represent the composite when all of its attributes are null 
@since 5.1 
@see Constant Field Values 

사실 짜잔로 hibernate.create_empty_composites.enabled 속성을 설정!

+0

고마워, 이건 좋은거야. 그러나 질문은 EBean과 관련이 있습니다. Hibernate는 아마 많은 측면에서 우수하지만, Ebean은 소규모 프로젝트와 더 잘 어울립니다. – allprog

1

최대 절전 모드에서 동일한 문제가 발생했습니다. 원래의 질문에 대한 "이유"에 대한 답변입니다. 해결책에 대해 이야기하지만

, 방금 클래스 내에 있도록하는 @PostLoad 방법을 사용 베더 뭔가 같은 :

@PostLoad 
private void initData() { 
    if(notAutoInstantiated == null) { 
    notAutoInstantiated = new NotAutoInstantiated(); 
    } 
} 

업데이트 :

경고! 상위 코드가 작동하지만 예기치 않은 부작용이 있습니다! 데이터베이스에서 널 포인터로 객체를로드하자 마자이 포스트로드 코드 때문에 더티로 표시됩니다! 필자의 경우,이 부작용으로 인해 스레드에서 SQL 업데이트 명령을받습니다. 스레드는이 버그를 검색하는 데 시간과 데이터 만로드해야합니다.