2013-03-19 2 views
2

도저 프레임 워크를 올바르게 평가하고 있습니다.요청에 따라 클래스 인스턴스를 생성하는 방법은 무엇입니까?

클래스 :

public ClassA { 

    private Set<ItemA> aItems; 
} 

public ClassB { 

    private ClassC cInstance; 
} 

public ClassC { 

    private List<ItemB> bItems; 
} 

도저 매핑 : 지금까지 내 testings를에서

<mapping> 
    <class-a>ClassA</class-a> 
    <class-b>ClassB</class-b> 
    <field> 
     <a>aItems</a> 
     <b>cInstance.bItems</b> 
    </field> 
</mapping> 

,이하지 않는 것 나는 다음과 같은 사용 사례를 처리 할 수 ​​있는지 궁금 해서요 일하다. 저는 Dozer에게 ClassB ClassC 인스턴스를 필요에 따라 생성해야한다고 어떻게 말해야합니까? 특히 대상 모델에 "중간"클래스로만 존재하는 ClassB에 대한 특정 도저 매핑이 필요합니까?

추신 : 도움이된다면, 내 대상 모델은 JAXB 클래스의

PPS를 구성 : 나는 또한 null의 경우는 ClassC의 새로운 인스턴스를 생성해야 cInstance에 대한 setter 메소드 수정을 시도 - 불행히도없이을 행운. 게다가, 나는 그런 식으로 setter 메소드를 수정하고 싶지 않다. (매핑을 위해 사용될 Factory 클래스에 이것을 아웃소싱 할 수있다.)

+0

와우, 여기서 무엇을하려고하는지 잘 모르겠습니다. Dozer를 복사 도구가 아닌 객체 팩터 리로 사용하려는 것 같습니다. – Perception

+1

cInstance 또는 getter에 대한 설정자를 수정 했습니까? 당신은 전자를 썼지 만 전자는 후자 여야합니다. [딥 매핑] (http://dozer.sourceforge.net/documentation/deepmapping.html)은 원하는 것처럼 들리지만 시도한 것과 비슷하기 때문에 어떻게 실패했는지 알 수 없습니다. [create method] (http://dozer.sourceforge.net/documentation/customCreateMethod.html)는 'cInstance' 필드가 이미 초기화되어있는 경우 ClassB 인스턴스를 생성하는 데 도움이 될 수 있습니다. – MvG

+0

@MvG에 감사드립니다. 그래, 당신 말이 맞을 것이다. 나는 getter가 아니라 setter를 수정했다. 그래서 나는 그것을 다른 방향으로 시도 할 것이다. 당신은 더 깊은 매핑을 시도하고있는 것이 옳다. 특정 create 메소드로 해결 방법을 시도 하겠지만 (처음에는 대상 모델의 생성 된 JAXB 클래스를 수정하려고하지 않았다.) – zazi

답변

0

그래서 내 대상 클래스가 JAXB 클래스이기 때문에 최종 솔루션은 오히려 간단하다는처럼 보이는, 내가 단순히를 활용할 수 JAXB 클래스의 디폴트 팩토리 (org.dozer.factory.JAXBBeanFactory). 팁점은 아마도 딥 매핑 대상 필드에 직접 액세스해야한다는 것입니다 ('is-accessible = "true"'). 그러나 ClassA.aitems에서 ClassC.cItems로 직접 맵핑을 추가로 만들었지 만 (그러나 이것이 ClassA 매핑에 설명 된 ClassA에 사용되는지 여부는 100 % 확신 할 수 없습니다). 어쨋거나, 마침내 공장 코드가 거의 필요없고 간단하고 직관적 인 솔루션을 찾았습니다.

0

Dozer에 대한 경험이 없다. 설명서는 다음과 같은 일을해야 다음 dozer BeanFactory interface 구현 ClassB에 대한 custom bean factory 만들기 : 당신의 필드는 정말 개인 경우

public class FactoryB implements BeanFactory { 
    public Object createBean(Object source, Class sourceClass, 
          String targetBeanId) { 
    assert(sourceClass.equals(ClassA.class)); 
    assert(ClassB.class.getName().equals(targetBeanId)); 
    ClassA a = (ClassA)source; 
    ClassB b = new ClassB(); 
    if (a.aItems != null && !a.aItems.isEmpty()) 
     b.cInstance = new ClassC(); 
    return b; 
    } 
} 

을, 그리고 당신이 그들에 대한 공공 접근을하지 않아도, 당신은 액세스 제한을 회피해야 할 수도 있습니다, JAXB 생성 클래스의 경우에는 그렇지 않습니다. 이제

이 같은 deep mapping 물건을지도 할 수 있어야한다 :

<mapping> 
    <class-a>ClassA</class-a> 
    <class-b bean-factory="FactoryB">ClassB</class-b> 
    <field> 
     <a>aItems</a> 
     <b>cInstance.bItems</b> 
    </field> 
</mapping> 
+0

답장을 보내 주셔서 감사합니다. @MvG. 지금까지 dozer 매뉴얼을 이해하는 한, org.dozer.factory.JAXBBeanFactory를 bean factory로 정의한 다음 생성 된 JAXB 클래스의 관련 ObjectFactory를로드합니다. 그러나 어쩌면 dozer의 요구 사항과 관련된 다른 팩토리를 만들고 정의해야 할 수도 있습니다. – zazi

+0

@ zazi : JAXB 팩토리는 객체를 모두 만들지 만 필요할 경우에만 초기 cInstance를 생성하지 못합니다. 스키마가 이미 bItem이 비어 있지 않은 경우에만 객체가 존재 함을 이미 정의하지 않은 경우. 어쨌든 내 코드에서 새로운 ClassB()와 새로운 ClassC()를 JAXB 팩토리로 대체 할 수있다. 팩터 리가 똑같은 일을하기를 기대한다. – MvG

+0

행운을 불어 넣지 만 대상 필드에서 제안을 (또한 작성 방법과 함께) 시도했습니다. 그것은 여전히 ​​NPE를 던지고 정말로 이유를 알 수 없습니다. – zazi

관련 문제