Serialize a JAXB object by its identifier?

In my data model, I have something like that:

@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... */ } 

I already serialize Target just fine, but I need to serialize Dependency . Essentially, I need something like this:

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

Is there a way to do this in a JAXB annotation without changing my model?

+4
source share
2 answers

You can use the XmlAdapter for this use case:

 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 registered in the Dependency class using the @XmlJavaTypeAdapter annotation:

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

Further

Instead of creating a new Target instance Target we could use the EntityManager to query the corresponding instance from the database. Our XmlAdapter will be resized to look something like this:

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

Now, to install an EntityManager instance on our XmlAdapter , we can do the following:

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

It works for EclipseLink MOXy with XmlID and XmlIDRef (but does not work for Sun JAXB, where XmlID should be a string)

 @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; } 
+2
source

Source: https://habr.com/ru/post/897647/


All Articles