通过其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
。 基本上,我需要的是这样的事情:
100 200
有没有办法在JAXB注释中执行此操作而不修改我的模型?
您可以在此用例中使用XmlAdapter
:
package forum7278406; import javax.xml.bind.annotation.adapters.XmlAdapter; public class TargetAdapter extends XmlAdapter { @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; } }
走得更远
我们可以使用EntityManager
从数据库中查询相应的实例,而不仅仅是创建Target
的新实例。 我们的XmlAdapter
将更改为:
package forum7278406; import javax.persistence.EntityManager; import javax.xml.bind.annotation.adapters.XmlAdapter; public class TargetAdapter extends XmlAdapter { 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; } }
现在要在我们的XmlAdapter
上设置EntityManager
的实例,我们可以执行以下操作:
Unmarshaller umarshaller = jaxbContext.createUnmarshaller(); TargetAdapter targetAdatper = new TargetAdapter(entityManager); unmarshaller.setAdapter(targetAdapter);
它适用于带有XmlID和XmlIDRef的EclipseLink MOXy(但是对于sun 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; }