Skip to main content

Request no.3 - not allow shared objects

1 reply [Last post]
kirillcool
Offline
Joined: 2004-11-17
Points: 0

Original request - May be adopt XMLBeans interface of adding attributes instead of createing them. This way, you will prevent accidental sharing of objects throughout the hierarchy, and even the infinite circular dependencies.
Kohsuke response - Could you elaborate on this?

In JAXB and JAXB 2.0, you use ObjectFactory to create an instance, use setters to set the attributes, and then use setter of the containing class to set this instance:
[pre]
final HeadType head = objFactory.createHeadType();
final PersonType headPerson = objFactory.createPersonType();
headPerson.setId(objFactory.createId(BigInteger.valueOf(100L)));
headPerson.setName(objFactory.createName("Bob"));
head.setPerson(headPerson);
[/pre]

In XMLBeans and C24, there is no need to call the final setter:
[pre]
final HeadType head = org.addNewHead();
final PersonType headPerson = head.addNewPerson();
headPerson.setId(BigInteger.valueOf(100L));
headPerson.setName("Bob");
[/pre]
This prevents the user from "sharing" the same object in different places in the hierarchy. This also prevents circular dependencies in the hierachy (what does JAXB do in this case?). The same goes for collections, the add() function returns the newly created object which was internally added to the underlying collection.

Both XMLBeans and C24 provide the setter function. The implementation of XMLBeans is unavailable (well, you always can decompile it), but in C24, each object stores a link to its father. I don't know how exactly they handle the circular dependencies, but my proposition is:

For every class attribute (both XML attribute and XML subelement), provide create() and get() functions in the class itself (not in the ObjectFactory, the implementation may go to the ObjectFactory, though).
For collections, provide add() and get() function. The get() function should have the word List in it to indicate that it returns a list.

As the ultimate result is an XML string, there should be little objection of having to create instance for each node in the hierarchy. The main argument - when unmarshalling, it's not JAXB's decision to allocate as few objects as possible for the hierarchy. There should be a separate class instance for each XML tag.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
jfialli
Offline
Joined: 2003-06-16
Points: 0

> Original request - May be adopt XMLBeans interface
> of adding attributes instead of createing them. This
> way, you will prevent accidental sharing of objects
> throughout the hierarchy, and even the infinite
> circular dependencies.

A JAXB 2.0 goal is to map POJO to XML.
For JAXB 2.0, JAXB will be supporting both java to xml
and xml to java. Typically, JavaBeans don't dictate
the method relationships you described above.

My impression of XMLBeans 1.0 is that it provides
a Java veneer over a xml infoset preserving data format.
So the API above is natural since each DOM node
typically has a parent and a document it belongs to.
The underlying data format dictates the API's that you described above. It promotes features of DOM into the API, something JAXB was trying to avoid.

For JAXB, there is no requirement to preserve an infoset
underneath the java representation. JAXB objects do not
expose a method that gets a parent object. JAXB designers are trying to keep the representation lean and
mean, not as bloated as DOM. One does not
experience a circularity issue unless one sets
a JAXB object that is identifiable (contains an xs:ID)
into multiple properties in the graph. The marshaller/validator should warn when this occurs. This
is the one case that JAXB user needs to be sure to
reference (via xs:IDREF).

-Joe Fialli, Sun Microsystems

> Kohsuke response - Could you elaborate on this?
>
> In JAXB and JAXB 2.0, you use ObjectFactory to create
> an instance, use setters to set the attributes, and
> then use setter of the containing class to set this
> instance:
> [pre]
> final HeadType head =
> e head = objFactory.createHeadType();
> final PersonType headPerson =
> Person = objFactory.createPersonType();
>
>
>
>
>
>
> headPerson.setId(objFactory.createId(BigInteger.value
> Of(100L)));
>
>
>
>
>
> headPerson.setName(objFactory.createName("Bob"));
> head.setPerson(headPerson);
> [/pre]
>
> In XMLBeans and C24, there is no need to call the
> final setter:
> [pre]
> final HeadType head = org.addNewHead();
> final PersonType headPerson =
> Person = head.addNewPerson();
> headPerson.setId(BigInteger.valueOf(100L));
> headPerson.setName("Bob");
> [/pre]
> This prevents the user from "sharing" the same object
> in different places in the hierarchy. This also
> prevents circular dependencies in the hierachy (what
> does JAXB do in this case?). The same goes for
> collections, the add() function returns the newly
> created object which was internally added to the
> underlying collection.
>
> Both XMLBeans and C24 provide the setter function.
> The implementation of XMLBeans is unavailable (well,
> you always can decompile it), but in C24, each object
> stores a link to its father.
Just as DOM node does. JAXB objects are not required
to store a link to their parent.

> I don't know how exactly
> they handle the circular dependencies, but my
> proposition is:
>
> For every class attribute (both XML attribute and XML
> subelement), provide create() and get() functions in
> the class itself (not in the ObjectFactory, the
> implementation may go to the ObjectFactory, though).
>
> For collections, provide add() and get() function.
> The get() function should have the word List in it to
> indicate that it returns a list.
>
> As the ultimate result is an XML string, there should
> be little objection of having to create instance for
> each node in the hierarchy. The main argument - when
> unmarshalling, it's not JAXB's decision to allocate
> as few objects as possible for the hierarchy. There
> should be a separate class instance for each XML tag.