users@jaxb.java.net

Re: Using existing classes

From: Greg Scott <gptscott_at_googlemail.com>
Date: Wed, 29 Aug 2007 18:52:15 +0100

Sorry but I don't see how this answers my question at all. Even if we forget
about EJB, consider it a client application, are people not encountering
this problem I've (and Gary) described?


On 8/28/07, Dmitri Colebatch <dim_at_colebatch.com> wrote:
>
> Hi Gary,
>
> In general, what I like the idea of (and this isn't always easy to do)
> is a class like this:
>
> @Entity
> @XmlRootElement
> class Widget
> {
> @Id
> @XmlTransient
> int id;
>
> @XmlElement
> @Column
> String name;
>
> @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY)
> @JoinColumn(name="order_id", referencedColumnName = "id")
> @OrderBy("id")
> @XmlElementWrapper(name="Parts")
> @XmlElement(name="Part")
> List<Part> parts;
>
> void someBusinessMethod() { ... }
> }
>
> This gives three things:
> 1. O/R mapping using EJB3 annotations
> 2. O/XML mapping using JAXB
> 3. Business logic.
>
> I dare say there are many arguments against this, but I think it gives
> a nice set of benefits.
>
> My real downside is that the JAXB design assumes that the object class
> hierarchy is the same as the XSD hierarchy. EJB3 annotations have
> their own set of restrictions as well... as a result this is only
> really usable for greenfield development unless you're really lucky.
>
> One of my main gripes on this approach is that it isn't possible
> (afaik) to change the order of elements defined in a superclass. Eg,
> I cant have this:
>
> class PricedWidget extends Widget
> {
> @Column
> @Element
> BigDecimal price;
> }
>
> and get XML like this:
>
> <widget>
> <name>box</name>
> <price>13.99</price>
> <parts>
> <part> ... </part>
> </parts>
> </widget>
>
> There are many "errors" in the above example, but I hope it conveys
> the problem. XML Schema doesn't let a subtype insert elements to a
> sequence, you can only add to the end of the sequence. Thus instead
> of the above you get:
>
> <widget>
> <name>box</name>
> <parts>
> <part> ... </part>
> </parts>
> <price>13.99</price>
> </widget>
>
> Which irks me... Does anyone have any suggestions for how to best get
> the price before parts? Obviously in this simple example it doesn't
> matter, but in more complex scenarios it does matter.
>
> cheers,
> dim
>
>
>
> On 8/28/07, Greg Scott <gptscott_at_googlemail.com> wrote:
> >
> >
> > Hello,
> >
> >
> >
> > I have been searching the JAXB documentation for a discussion of a
> > design-related problem I have with JAXB and incorporating it into an
> design
> > (set of classes and interfaces). Reassuringly, I found this posting from
> > this mailing list which almost completely captured my exact same problem
> (I
> > have pasted it below):
> > https://jaxb.dev.java.net/servlets/ReadMsg?listName=users&msgNo=150
> >
> >
> >
> > I noticed this was from 2002! Given the old age of this posting, could I
> > raise this issue again, in the hope that, with the newer versions of
> JAXB or
> > different thinking, someone could offer a better way around this problem
> > than that suggested in (1).
> >
> >
> >
> > Many thanks for any advice.
> >
> >
> >
> > Greg Scott
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > Date: Tue, 24 Dec 2002 11:39:00 -0500
> >
> > From: Gary Gregory <ggregory_at_seagullsw.com >
> >
> > Subject: Using existing classes
> >
> > Content-type: multipart/alternative;
> >
> > boundary="Boundary_(ID_58uuYtbp6qs51bz0CUtMnw)"
> >
> >
> >
> > We have been dealing with the same situation here. I will just share our
> >
> > current solution and thoughts (=ramblings). There are two main issues I
> >
> > think: (1) Integrating JAXB generated code and (2) Deciding on a per app
> >
> > basis what JAXB means to you.
> >
> >
> >
> > (1) Clearly, being able to generate the JAXB model classes as a
> subclasses
> >
> > of custom classes would be quite practical at first. You would end up
> with,
> >
> > for example, a Customer class and an XMLCustomer subclass, where the
> latter
> >
> > was generated by JAXB. But, is this a proper use of inheritance? Do you
> >
> > really want "an XML kind of customer"? It seems (to me) that this looks
> too
> >
> > heavyweight of an architecture and also very brittle. You could end up
> with
> >
> > one XML subclass for every single class in your app model, possibly
> spread
> >
> > over many packages. In a general sense, adopting such an architecture
> would
> >
> > mean that for every encoding (XML, JDBC, or whatever) of such a model
> class
> >
> > would require a new subclass. Certainly, after a couple of encoding
> >
> > implementation, you would end up refactoring common behavior into...
> what? A
> >
> > CustomerMarshaller subclass which in turn has an XMLCustomer subclass?
> >
> > Nah... I claim that this is situation calls for composition, not
> >
> > inheritance. The Customer class can have an instance variable that holds
> on
> >
> > to it's "binding", the JAXB generated object. You can also add an
> "adaptor"
> >
> > layer to shield the model class from any changes to the underlying
> binding.
> >
> > This does not 'feel' like to best solution.
> >
> >
> >
> > (2) The more general issue I have with JAXB can be subdivided into two
> >
> > areas: (a) Where do you start and (b) How much do you put into the XML
> >
> > Schema. I threw away a lot of my implementation when I ported our
> >
> > still-in-development app from object-based unit test fixtures to XML
> data
> >
> > file based unit test fixtures. Why? When you start with JAXB, you start
> with
> >
> > XML Schema. When you unmarshall, an XML data file with JAXB, you get a
> >
> > custom object tree based on the classes defined by the XML Schema. What
> did
> >
> > I have before? I already had a custom object tree in my unit tests. I
> >
> > already had a app model set of classes. Now I had both. What feels like
> a
> >
> > step back with JAXB is that the generated code defines state only. The
> app
> >
> > model I had contained both state and behavior of course, like in any
> decent
> >
> > OO design. But, to make things more complicated, the JAXB generated code
> >
> > does not have to be stateless, strictly speaking. XML Schema is pretty
> >
> > powerful stuff, and since you can specify all manners of restrictions
> and
> >
> > data validation on the data contained in attributes and elements, these
> >
> > specification do get translated into code. There can be (optionally),
> some
> >
> > amount of clever behavior in the JAXB model code. You can get behavior
> like
> >
> > data validation in your JAXB model classes. Now, I have two big
> conceptual
> >
> > piles: JAXB model class with some state and some behavior plus my app
> model
> >
> > with all of the state and all of the behavior. (I would say that most
> apps
> >
> > would have additional transient state in their model that do not get
> >
> > externalized.) Assuming that avoiding duplication is not acceptable,
> what to
> >
> > do?
> >
> >
> >
> > For good or bad, here is what we did:
> >
> > Start with XML-Schema. This forced us to decide what should really be
> >
> > persisted in the first place.
> >
> > Use JAXB to generate code into a com.company.component.bind package.
> Since
> >
> > the general category of code generated belongs in the "XML data binding"
> >
> > category, we felt "bind" was a good name. The "bind" packages contains
> only
> >
> > JAXB generated code. Create a class called
> com.company.component.Bindings
> >
> > that hides JAXB details and provide type safe methods like
> >
> > unmarshalCustomer. A root model class is in com.company.component like
> >
> > com.company.component.Customer. Customer has an ivar called
> customerBinding
> >
> > (we postfix JAXB generated class names with "Binding"). Customer
> delegate to
> >
> > the binding getters and setters. Anything that requires binding data
> >
> > structure traversal is done in the Bindindgs class.
> >
> >
> >
> > I am not 100% satisfied with this arrangement but I like delegating to a
> >
> > binding class instead of using inheritance as a hack to get my behavior
> for
> >
> > "free". Inheritance does not feel right to me: what if I want to save a
> >
> > Customer to a database? Do I have to create a JDBCCustomer subclass
> of...
> >
> > Customer? Not of XMLCustomer. But I have instances of XMLCustomer flying
> >
> > around my app... What if I had a "clean" Customer with all state and
> >
> > behavior, then I would just instantiate my XML or JDBS subclass
> just-in-time
> >
> > for that encoding/decoding task. But then I would need marshalling code
> >
> > to/from the XML/JDBC subclass, which seems to be redundant with what
> happens
> >
> > in JAXB already. Using an encoding subclass in a just-in-time manner
> also
> >
> > means that your app would not catch validation error until the last
> second,
> >
> > unless you where to duplicate code, which is not acceptable to me (in a
> >
> > perfect world). If the case of an app with a UI, if the model is backed
> by a
> >
> > binding object, you would be able the give feedback right away when an
> error
> >
> > is detected in data validation.
> >
> >
> >
> > JAXB poses some interesting design issues and I wish Sun would at least
> talk
> >
> > about them in the JAXB docs/specs. BTW, I did not even mention
> subclassing
> >
> > the JAXB generated code which I consider would create the most brittle
> code
> >
> > and would be nasty. I think of all JAXB generated code as private to the
> >
> > "Bindings" helper class. Clearly, there has to be a better way, ot at
> least
> >
> > a cleaner way.
> >
> >
> >
> > Gary
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
> For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>
>