JPA Objects requires that all entities are
annotated with @DiscriminatorValue
. The
JPA Objects' metamodel validator will ensure this
is unique (though if it isn't, then the JPA provider
itself - ie Hibernate - would also throw up an exception).
In "standard" JPA the
@DiscriminatorValue
is only used to distinguish
between concrete subclasses within inheritance hierarchies. JPA Objects
makes this a mandatory requirement for all entities so that every entity
instance can be identified using the (discriminator, id) tuple.
This tuple is valuable for two reasons:
from a persistence viewpoint this tuple can be reused for
polymorphic relations, that is, as defined using
@Any
or
@ManyToAny
.
Naked Objects applications tend to be rather "purer" object models than domain models you might have used in non-NO applications, and - following SOLID principles - are likely to use interfaces to decouple classes in different modules. This does cause us to hit the object/relational mismatch though: a decoupled object model cannot rely on an RDBMS to enforce referential integrity, hence the use of polymorphic relations. See Section 2.5, “Specify a discriminator” for more discussion on this.
from an integration viewpoint, because this tuple is in effect a URN for each entity within the domain, then it can (in serialized form) be used for interacting to other systems (or bounded contexts, if you are use the domain-driven design jargon).
For example, a RESTful web service (eg as provided by Restful Objects) can use this URN with the path representing a resource, eg to read an object's property or to invoke an action upon it. Or, a message can be published asynchronously, and the URN be used as a correlation Id for a response message.
The tuple is also used internally by Naked Objects, in the
org.nakedobjects.metamodel.adapter.oid.Oid
interface, used to maintain an identity map of domain objects.
JPA Objects provides an implementation of this
interface,
org.starobjects.jpa.runtime.persistence.oid.JpaOid
,
which is precisely this tuple.
Going back to the @DiscriminatorValue
, the
recommended length is 3 or 4 characters. Putting this together with the
@Id
, we get something like:
@Entity @DiscriminatorValue("CUS") public class Customer { private Integer id; @Id public Integer getId() { return id; } private void setId(Integer id) { this.id = id } ... }
So Customer with id=12345 would have a URN
("CUS", 12345). The serialized form of this (as provided by
JpaOid
) is "CUS|12345".
See Section 4.9, “Polymorphic Relationships” for further discussion on how this tuple is reused for polymorphic relations.