2011-09-02 37 views
4

在我的數據模型,我有話要這樣的效果:通過其ID來序列化一個JAXB對象?

@Entity 
public class Target { 

    @Id 
    @GeneratedValue 
    private Long id; 

    /* ...etc... */ 
} 

@Entity 
public class Dependency { 

    @Id 
    @GeneratedValue 
    private Long id; 

    @ManyToOne(optional=false) 
    @Column(name="target_id") 
    private Target target; 

    /* ...etc... */ 
} 

我已經序列化Target就好了,但我需要序列Dependency。從本質上講,我需要的是這樣的:

<dependency> 
    <id>100</id> 
    <targetId>200</targetId> 
</dependency> 

有沒有辦法做到這一點在JAXB註解,而無需修改我的模型?

+0

是'streamId' ='Target.id' ? –

+0

是的,對不起,我的不好。 –

回答

7

你可以使用一個XmlAdapter這個用例:

package forum7278406; 

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

public class TargetAdapter extends XmlAdapter<Long, Target> { 

    @Override 
    public Long marshal(Target target) throws Exception { 
     return target.getId(); 
    } 

    @Override 
    public Target unmarshal(Long id) throws Exception { 
     Target target = new Target(); 
     target.setId(id); 
     return target; 
    } 

} 

XmlAdapter使用@XmlJavaTypeAdapter註釋在Dependency類中註冊:

package forum7278406; 

import javax.persistence.*; 
import javax.xml.bind.annotation.*; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

@Entity 
@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Dependency { 

    @Id 
    @GeneratedValue 
    private Long id; 

    @ManyToOne(optional=false) 
    @Column(name="target_id") 
    @XmlJavaTypeAdapter(TargetAdapter.class) 
    private Target target; 

    public Long getId() { 
     return id; 
    } 

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

    public Target getTarget() { 
     return target; 
    } 

    public void setTarget(Target target) { 
     this.target = target; 
    } 

} 

的進一步深入

而不是僅僅創造Target一個新的實例,我們可以使用一個EntityManager從數據庫中查詢相應的實例。我們XmlAdapter將改爲看起來像:

package forum7278406; 

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

public class TargetAdapter extends XmlAdapter<Long, Target> { 

    EntityManager entityManager; 

    public TargetAdapter() { 
    } 

    public TargetAdapter(EntityManager entityManager) { 
     this.entityManager = entityManager; 
    } 

    @Override 
    public Long marshal(Target target) throws Exception { 
     return target.getId(); 
    } 

    @Override 
    public Target unmarshal(Long id) throws Exception { 
     Target target = null; 
     if(null != entityManager) { 
      target = entityManager.find(Target.class, id); 
     } 
     if(null == target) { 
      target = new Target(); 
      target.setId(id); 
     } 
     return target; 
    } 

} 

我們設定的EntityManager實例我們XmlAdapter,我們可以做到以下幾點:

Unmarshaller umarshaller = jaxbContext.createUnmarshaller(); 
TargetAdapter targetAdatper = new TargetAdapter(entityManager); 
unmarshaller.setAdapter(targetAdapter); 
+1

這是勝利。 –

2

它適用於EclipseLink的莫西與XmlID和XmlIDRef(但失敗了太陽JAXB,其中XmlID必須是字符串)

@Entity 
@XmlRootElement 
public class Target { 
    @Id 
    @GeneratedValue 
    @XmlID 
    @XmlElement 
    private Long id; 
} 


@Entity 
@XmlRootElement 
public class Dependency { 

    @Id 
    @GeneratedValue 
    @XmlElement 
    private Long id; 

    @ManyToOne(optional = false) 
    @Column(name = "target_id") 
    @XmlIDREF 
    @XmlElement(name = "targetId") 
    private Target target; 
}