users@jpa-spec.java.net

[jpa-spec users] [jsr338-experts] Re: proposal : _at_Entity on interfaces

From: Matthew Adams <matthew_at_matthewadams.me>
Date: Wed, 14 Mar 2012 11:00:25 -0500

On Tue, Mar 13, 2012 at 7:43 PM, Pinaki Poddar <ppoddar_at_us.ibm.com> wrote:
> Using interfaces as model for persistent data and their relation for
> mapping them to relational database is a poor idea. Most likely rooted in
> confusion about
> distinct role of interfaces and stateful objects. That's all.
>
Taken without context, I agree with you, Pinaki. It is odd to think
about using interfaces within domain object models, especially if you
think of them in the context of dependency injection and the like.

However, now that I've written some behaviorally rich, persistent
domain object models using Java & AspectJ, that the use of interfaces
within an object model does have some benefit, but it takes a more
mature attitude than just black & white towards the use of interfaces.
 As in life, everything is a shade of grey.

The kind of interfaces I'm talking about using in a persistent domain
model are not "servicy", but "traity". That is, the interfaces that
I've found have a place within the domain object model layer are not
coarse-grained like a service-oriented interface. They are more like
stateful traits (a la Scala) that an entity may exhibit. For example,
I was working in the legal domain, and it turned out that many of the
entities we were modeling had court orders associated with them. We
naturally identified a HasOrders interface, which was the contract for
any entity that had court orders associated with it, which was simply
a unidirectional collection of documents. We wrote an AspectJ ITD
that was applied to any class declaring that it implemented the
HasOrders interface. With default mapping metadata inside the ITD, it
was a breeze to add this behavior basically as a stateful trait, to
any of our entities that needed it. Programmatically, we could treat
collections of HasOrders instances just fine, but we did run into
issues when some other entity needed to persist a field of type
HasCourtOrders or a collection thereof.

In these cases, and with the directions that Java appears to be going
toward in JDK 8 (basically, virtual extension methods as stateless
traits), I think that stateful traits might be in our future--not our
near future, mind you, but sometime, I think.

To me, the allowance for the persistence of interfaces is not a
question of ability, but one of difficulty. To me, the difficulty is
not identifying which classes implement which persistent interfaces;
that much is evident simply by annotating an interface as persistent
and observing which @Entity classes implement it. Also, the ability
to query over extents of persistent interfaces and through fields of
interface types doesn't seem too difficult, either, because the
metadata contains sufficient information to formulate a query that
includes all candidate instances that implement the interface type.
The difficulty lies in the mapping of polymorphic fields of interface
types (and of type java.lang.Object), because you not only have to map
the id of the referenced entity, but also its class.

If we were to identify a portable means by which to map the
implementation class of the polymorphic reference along with its id,
we'd be able to fully support persistent interfaces. Perhaps we use
the value of the "name" attribute of the concrete class's @Entity
attribute as an additional field. Perhaps we identify some other way.

The bigger question, to me, is simply should we specify it, and if we
do, should it be done in the 2.1 timeframe?

-matthew