Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[eclipselink-users] roundtripping POJOs via MOXy

Hi, MOXy Mavens:

Given a graph of POJOs with bidirectional relationships, what's the
best strategy
for using MOXy to marshall trees out of the graph as XML and, later or
elsewhere,
unmarshall the XML and merge it into a new graph?

The graph contains bi-directional one-to-many relationships between the POJOs.

Ideally, the marshalled XML would have an id (unique for the class) as well as a
few denormalized fields from each related object.  The denormalized fields
would be thrown away on merge.

The strategy has to be generic (ie, not coded to a specific set of POJOs).

I did take a look at:
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA/Relationships

I can use @XmlInverseReference() to embed a related object.  When I merge new
related objects, the object with the nested object gets a reference.
However, the
nested object doesn't get the inverse reference.

Also, I can use @XmlID / @XmlIDREF to embed ids for references.  However,
I can't unmarshall the generated XML.

Any suggestions on how best to leverage MOXy for this problem?

I've appended the basics from a sample after my signature.


Thanks in advance,


Erik Hennum


@Entity
@XmlRootElement
public class City {
    @Id
    @Column(name="ID")
    @XmlID
	private long id;

    @Column(name="NAME")
	private String name;

	@ManyToOne
    @JoinColumn(name="COU_ID", referencedColumnName = "ID")
	@XmlIDREF
	private Country country;

    // constructor and methods omitted ...
}

@Entity
@XmlRootElement
public class Country {
    @Id
    @Column(name="ID")
    @XmlID
	private long id;

    @Column(name="NAME")
	private String name;

    @OneToMany(mappedBy="country")
	@XmlInverseReference(mappedBy="country")
	private Set<City> cities;

    // constructor and methods omitted ...
}


	public static void main(String... args) throws JAXBException {
		int cityNo    = 1;
		int countryNo = 1;

		City london = new City();
		london.setId(cityNo++);
		london.setName("London");
		// other cities ...
		Country uk = new Country();
		uk.setId(countryNo++);
		uk.setName("United Kingdom");
		Set<City> ukCities = new HashSet<City>();
		ukCities.add(london);
		// other cities ...
		uk.setCities(ukCities);
		london.setCountry(uk);
		// other cities ...

		JAXBContext context = JAXBContext.newInstance(
				City.class, Country.class
				);

		Marshaller   marshaller   = context.createMarshaller();
		Unmarshaller unmarshaller = context.createUnmarshaller();

		StringWriter sw = new StringWriter();
		StringBuffer sb = sw.getBuffer();
		marshaller.marshal(uk, sw);
		System.out.println(sb.toString());
		sb.delete(0, sb.length());
		marshaller.marshal(london, sw);
		System.out.println(sb.toString());

		City x = (City) unmarshaller.unmarshal(new StringReader(sb.toString()));

		String germanyStr =
			"<country><id>3</id><name>Germany</name><version>0</version></country>";
		String berlinStr =
			"<city><id>5</id><country>3</country><name>Berlin</name><version>0</version></city>";

		StringReader sr = new StringReader(germanyStr);
		Country germany = (Country) unmarshaller.unmarshal(sr);
		sr = new StringReader(berlinStr);
		City berlin = (City) unmarshaller.unmarshal(sr);

		EntityManagerFactory emf =
			Persistence.createEntityManagerFactory("country");
		EntityManager em = emf.createEntityManager();

		germany = em.merge(germany);
		berlin  = em.merge(berlin);

		System.out.println(berlin.getName()+" "+
				berlin.getCountry());
		System.out.println(germany.getName()+", "+
				germany.getCities().size());

		em.close();
		emf.close();
	}


Back to the top