2012-08-24 2 views
4

apt stackoverflow 커뮤니티에 굴복하고 겸손하게 지침을 구합니다.JAXB는 EntityManager가 해제(), 폐쇄() 및 null로 설정된 경우에도 FetchType.LAZY로 표시된 필드를 열심히 가져옵니다.

@Entity 
@Table(name = "EVENTS") 
@XmlRootElement 
public class Event extends EventBase { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @XmlAttribute(name = "id") 
    private long eventCID; 

    @OneToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "APPLICATIONCID") 
    private CustomerApplication customerApplication; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "CUSTOMERCID") 
    private Customer customer; 

    .... 
} 

여기에 내 코드에의 (BTW EventBase 추가 필드를 보유하고 단지 @MappedSuperclass입니다) :

내가 JPA /는 EclipseLink/JAXB/목시 주석의 혼합물을 가지고 다음과 같은 Entity 클래스/콩 한

이 엔티티를 마샬링합니다 (간결성을 위해 외부 클래스 제외됨)

public static void main(String args[]) { 
    Event event = myInstance.populateEvent(); 
    myInstance.buildXMLFromEvent(event); 
} 

public Event populateEvent() { 

    EntityManagerFactory emf = Persistence.createEntityManagerFactory(this.persistenceUnit); 
    EntityManager em = null; 

    Event event = null; 
    try { 
     em = emf.createEntityManager(); 
     event = (Event) em.createQuery("Select object(e) from Event e where e.eventCID = 55000").getSingleResult(); 
     em.clear(); 
     em.detach(event); 
     em.close(); 
     em = null; 
     emf.close(); 
     emf = null; 
    } catch (Exception e) { // just test code so catching general exception 
     log.error("Unexpected error: " + e); 
    } finally { 
     if (em != null) { 
      em.clear(); 
      em.close(); 
     } 
    } 
    return event; 
} 

private void buildXMLFromEvent(Event event) { 

    System.out.println("Marshalling now:"); 
    JAXBContext jc; 
    try { 
     jc = JAXBContext.newInstance(Event.class); 
     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.valueOf(true)); 
     JAXBElement<Event> jaxbElement = new JAXBElement<Event>(new QName("event"), Event.class, event); 
     marshaller.marshal(jaxbElement, System.out); 
    } catch (JAXBException e) { 
    } 
} 

생성 된 xml은 실제로 내 Event Entity Bean의 모든 구성원 객체를 간절히 가져옵니다. 즉, Customer, CustomerApplication 및 기타 간략한 설명을 위해 제외 된 매핑. EclipseLink를 JPA 제공 업체로, Moxy를 JAXB 용으로 사용하고 있습니다. 여기서 내가 뭘 잘못하고 있니? entityManager 및 entityManagerFactory 인스턴스가 지워지고 닫히고 null로 설정 될뿐만 아니라 루트 이벤트 엔티티도 분리되었음을 알 수 있습니다. 또한 fetchtype은 명시 적으로 LAZY!로 설정되었습니다.

이벤트 객체가 분리되었을 때 JAXB가 어떻게 열렬히 가져올 수 있습니까? entityManager를 닫으면 모든 관리 객체가 분리되는 것 같습니다. JAXB가 걸려있는 캐시 된 세션 컨텍스트가 있습니까? 그렇다면 명시 적으로 정의 된 가져 오기 전략을 준수하지 않는 이유는 무엇입니까? 미리 감사드립니다.

스타드

+0

좋아, 클래스 수준에서 @XmlAccessorType (XmlAccessType.FIELD) 주석을 추가하면 이제 해당 멤버 개체를 가져올 수 없습니다. 나는 여전히 개체가 닫힌/지워진/null entityManager를 사용하여 가져올 수있는 방법에 대해 여전히 혼란 스럽다. 뭔가를 놓치지 않는 한 - 나는 아마있을 것이다! – ustad

+1

엔티티를 직접 노출 시켜서 디자인을 개선하고, DTO 객체를 생성하고, 직접 뷰를 제어 할 수있는 것은 좋지 않습니다. –

+0

안녕 Alexey, 감사합니다. 예제가 반드시 필요한 것은 아닙니다. 내 디자인을 비추고, 일러스트레이션을 위해 이것을 만들었습니다 ... – ustad

답변

2

는 EclipseLink 독립 모드에있는 경우 다른 속성을 무시하고 EAGER 동일 페치를 들어, 만 ManyToMany 및 OneToMany 관계, 실제로 게으른 로딩을 사용합니다. 여기

은에 대한 문서입니다 http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Mapping/Basic_Mappings/Lazy_Basics

일대일 : 기본적으로는 EclipseLink JPA는 가져 오기 속성과 javax.persistence.FetchType.EAGER 적용 기본을 무시합니다.

many-to-one : EclipseLink JPA는 속성을 가져올 때 지연 수신을 수행합니다 (javax.persistence.FetchType.LAZY로 설정).

기본 : 기본적으로 EclipseLink JPA는 fetch 속성을 무시하고 기본 javax.persistence.FetchType.EAGER가 적용됩니다.

그래서 엔티티에 관계가로드됩니다.

희망이 있습니다.

+1

연구 및 도움에 감사드립니다! 그 참조 문서는 매우 유용합니다! 가져 오기 전략은 내가 가진 관계에도 불구하고 항상 EAGER였습니다. 질문을 게시 한 후 첫 번째 댓글을 보시기 바랍니다. 다시 붙여 드리겠습니다. _ "클래스 수준에서 @XmlAccessorType (XmlAccessType.FIELD) 주석을 추가하면 이러한 멤버 객체가 가져 오지 못하게되었습니다. 나는 여전히 개체가 닫히고/지워진/null 엔티티 관리자를 통해 페치 될 수있는 방법에 대해 여전히 혼란 스럽다. 나는 뭔가를 놓치지 않는 한 - 나는 아마있을 것이다! "_ 나는 아직도 그 해답을 모른다. . tnx! – ustad

+0

eager fetch 유형을 사용하면 event = (Event) em.createQuery ("e.eventCID = 55000 인 이벤트 e에서 객체 선택 (e)). getSingleResult();를 호출하면 모든 관계가 페치됩니다. XML의 관계가 모두있는 이유라고 생각합니다. 그러나 jaxb의 필드 액세스로 해결할 수있는 방법을 이해할 수 없습니다. 유일한 생각은 당신은 그 들판에 게터가 없다는 것입니다. –