2011-07-27 4 views
6

지난 며칠 동안 MOXy JAXB를 사용하여 Hibernate 모델의 XML 마샬링/언 마샬링에 대한 지원을 시도했습니다. 이렇게하려고하면 최대 절전 모드 프록시 개체에 문제가 발생했습니다. 같은 것을 생각해(moxy) jaxb 마샬링 및 프록시 객체

@XmlAccessorType(XmlAccessType.NONE) 
public class User { 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "address") 
    @XmlElement 
    public Address getAddress() { 
     return address; 
    } 
} 

@XmlAccessorType(XmlAccessType.NONE) 
@XmlSeeAlso(CoolAddress.class) 
public abstract class Address { 
    // Something 
} 

@XmlAccessorType(XmlAccessType.NONE) 
public class CoolAddress extends Address { 
    @XmlElement 
    public String getSomething() { 
     return something; 
    } 
} 

내 문제가 최대 절전 모드가 getAddress에 호출하여 얻은 주소의 프록시 객체를 인스턴스화입니다 :

public class User { 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "address") 
    public Address getAddress() { 
     return address; 
    } 
} 

public abstract class Address { 
    // Something 
} 

public class CoolAddress extends Address { 
    public String getSomething() { 
     return something; 
    } 
} 

나는 다음과 같은 방법으로 목시 JAXB를 사용하여이 코드를 매핑하는 시도()를 사용합니다. 그런 다음 JAXB가 객체를 마샬링하려 할 때 실제로 마샬링하려고하는 CoolAddress인지 알 수 없으므로 CoolAddress의 속성이 마샬링되지 않습니다. 나 서로 마샬링되는 개체를 대체 할 수 있도록, JAXB에서 콜백을받을

  • 어떤 방법으로 :

    내가 검색 좀이/다음과 같은 가능한 솔루션을 고려했다. 이렇게하면 프록시에서 실제 개체를 얻을 수 있습니다.

  • 모델에서 실제 객체를 최대 절전 모드로 가져 오는 모든 객체를 터치합니다. 조용한 지루한 모든 비 일시적인 속성을 수동으로 실행하는 것 외에는 현명한 방법을 찾을 수 없었습니다.
  • 세션에서 eager fetching을 사용하기 위해 최대 절전 모드를 설정합니다. 모델을 마샬링하고 있습니다.

나는 대안을 찾고 있는데, 위의 제안 중 하나가 구현 가능하고 (그리고 쉬운) 경우. 어떤 도움을 주셔서 감사합니다 :).

+0

'CoolAddress'가'Address'를 확장합니까? –

+0

예, 죄송합니다. 나는 그것을 쓰는 것을 잊어 버렸다. –

답변

6

이 최대 절전 모드 문제를 해결하기 위해 XmlAdapter을 사용할 수 있습니다.다음과 같이

package forum6838323; 

import javax.xml.bind.annotation.adapters.XmlAdapter; 

public class AddressAdapter extends XmlAdapter<Address, Address> { 

    @Override 
    public Address unmarshal(Address v) throws Exception { 
     return v; 
    } 

    @Override 
    public Address marshal(Address v) throws Exception { 
     // TODO Auto-generated method stub 
     return null; 
    } 

} 

당신은 XmlAdapter를 구성 : 정렬 화 방법의 논리는 실제 개체에 프록시 변환하는 경우처럼 (때문에) XmlAdapter이 보일 것입니다 당신이 통과해야하는 경우

public class User { 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "address") 
    @XmlJavaTypeAdapter(AddressAdapter.class) 
    public Address getAddress() { 
     return address; 
    } 
} 


대체

주 :는 EclipseLink JPA의 게으른 로딩이 문제가 발생하지 않습니다

사용자를

package forum6838323; 

import javax.persistence.*; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlRootElement; 

@Entity 
@Table(name="users") 
@XmlRootElement 
public class User { 

    private int id; 
    Address address; 

    @Id 
    @XmlAttribute 
    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "address") 
    public Address getAddress() { 
     return address; 
    } 

    public void setAddress(Address address) { 
     this.address = address; 
    } 

} 

주소

package forum6838323; 

import javax.persistence.*; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlSeeAlso; 

@Entity 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.STRING) 
@DiscriminatorValue("ADDRESS") 
@XmlSeeAlso(CoolAddress.class) 
public class Address { 

    private int id; 
    private String street; 

    @Id 
    @XmlAttribute 
    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getStreet() { 
     return street; 
    } 

    public void setStreet(String street) { 
     this.street = street; 
    } 

} 

CoolAddress

package forum6838323; 

import javax.persistence.*; 

@Entity 
@DiscriminatorValue("COOL") 
public class CoolAddress extends Address { 

    private String something; 

    public String getSomething() { 
     return something; 
    } 

    public void setSomething(String something) { 
     this.something = something; 
    } 

} 

데모

package forum6838323; 

import javax.persistence.EntityManager; 
import javax.persistence.EntityManagerFactory; 
import javax.persistence.Persistence; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     EntityManagerFactory emf = Persistence.createEntityManagerFactory("Forum6838323"); 
     EntityManager em = emf.createEntityManager(); 

     User user = em.find(User.class, 2); 
     System.out.println("user.address BEFORE marshal: " + user.address); 

     JAXBContext jc = JAXBContext.newInstance(User.class); 
     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(user, System.out); 

     System.out.println("user.address AFTER marshal: " + user.address); 
    } 

} 

출력

당신은 출력에서 ​​볼 수있는 주소 발 ue는 마샬링되기 전에 필드가 null이어서 나중에 채워지기 때문에 느리게로드됩니다.

user.address BEFORE marshal: null 
[EL Finest]: 2011-07-27 11:47:13.118--ServerSession(23503403)--Thread(Thread[main,5,main])--Execute query ReadObjectQuery(name="Forum6838323" referenceClass=Address) 
[EL Finest]: 2011-07-27 11:47:13.118--ServerSession(23503403)--Connection(10272075)--Thread(Thread[main,5,main])--Connection acquired from connection pool [default]. 
[EL Fine]: 2011-07-27 11:47:13.118--ServerSession(23503403)--Connection(10272075)--Thread(Thread[main,5,main])--SELECT ID, TYPE, STREET, SOMETHING FROM ADDRESS WHERE (ID = ?) 
    bind => [2] 
[EL Finest]: 2011-07-27 11:47:13.118--ServerSession(23503403)--Connection(10272075)--Thread(Thread[main,5,main])--Connection released to connection pool [default]. 
[EL Finest]: 2011-07-27 11:47:13.118--UnitOfWork(6131844)--Thread(Thread[main,5,main])--Register the existing object [email protected] 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<user id="2"> 
    <address xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="coolAddress" id="2"> 
     <street>2 B Road</street> 
     <something>Cool Road</something> 
    </address> 
</user> 
user.address AFTER marshal: [email protected] 
+1

아주 좋은 대답을하기보다는. –

관련 문제