2011-07-27 23 views
6

Son birkaç gün içinde, MOXy JAXB kullanarak bir Hazırda Bekleme modelinin XML marshalling/unmarshalling'i için destek yapmaya çalıştım. Bunu yapmaya çalışıyorum, hazırda bekletme nesnelerini kullanarak bir sorunla karşılaştım. gibi bir şey düşünün:(moxy) jaxb klikleme ve hazırda bekleme vekil nesneleri

@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; 
    } 
} 

Benim sorunum şu hazırda GetAddress arayarak elde adresinin bir vekil nesnesini başlatır geçerli:

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; 
    } 
} 

aşağıdaki şekilde Moxy JAXB kullanarak bu kodu eşleştirmek için çalıştık() Bir Kullanıcıda. Daha sonra, JAXB nesneyi mareşal etmeye çalıştığında, aslında CoolAddress'in marşalize edilmemesiyle sonuçlanan, CoolShield'ın marshal yapmaya çalıştığı bir CoolAddress olduğunu öğrenemez. Beni başkasıyla Sıralanmış nesne yerine izin JAXB bir geri almak

  • Bir şekilde:

    Ben googled var/aşağıdaki olası çözümleri düşündü. Bu, gerçek nesneyi proxy'den almamı sağlar.

  • Modeldeki tüm nesnelere dokunarak, nesnelere gerçek nesneleri getirmeye hazır hale getirin. Geçici olmayan tüm geçici özelliklerle manuel olarak koşmaktan daha akıllıca bir yol bulamadım, bu da sıkıcı bir sıkıcı.
  • Oturumda istekli getirme kullanmak için hazırda bekletme modunu ayarlayın Modelleri sıraya diziyorum.

Alternatif öneriler arıyorum veya yukarıdaki önerilerden birinin uygulanmasının mümkün olup olmadığı (ve kolay). Herhangi bir yardım takdir edilir :).

+0

'CoolAddress' 'Adresi' uzatıyor mu? –

+0

Evet, pardon. Bunu yazmayı unuttum. –

cevap

6

Bu Hazırda bekleme sorunu çözmek için XmlAdapter kullanabilirsiniz.aşağıdaki gibi

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; 
    } 

} 

Sen XmlAdapter yapılandırmak: mareşal yönteminde mantık gerçek nesneye proxy'den dönüştürmek olduğu gibi XMLAdapter görünecektir geçmek gerekirse

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


Alternatif

Not: EclipseLink JPA geç yükleme bu soruna neden olmaz:

Kullanıcı

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; 
    } 

} 

Adres

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; 
    } 

} 

Demo

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); 
    } 

} 

Çıktı

Sen çıkışından görebilirsiniz adres val alan mareşal önce null olduğundan ve sonradan doldurulduktan sonra tembel olarak yükleniyor:

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

Çok güzel bir cevabınız için. –

İlgili konular