Oliver/all,
Hope, this is the email alias, that works for posting to the JPA list?;-)
Both an additional annotation @EntityAlias and the extensive list of classes/interfaces if it was just a single annotation seem a bit odd, but from a clean and simple code point of view I may lean towards the second annotation.
Using Interfaces rather than concrete classes within entities has also been an issue in JPA 2. If any on the list came across a similar issue or feel demand, I am happy to turn the actual code into a sample I can share here or on JIRA.
Werner
-------- Original-Nachricht --------
> Datum: Mon, 12 Mar 2012 05:08:26 -0700
> Von: Oliver Gierke <ogierke_at_vmware.com>
> An: "jsr338-experts_at_jpa-spec.java.net" <jsr338-experts_at_jpa-spec.java.net>
> CC: Matthew Adams <matthew_at_matthewadams.me>, "Bernd Müller" <bernd.mueller_at_ostfalia.de>
> Betreff: [jsr338-experts] Re: proposal : @Entity on interfaces
> +1 on Mike's statement here. My initial intention (and I think Steve's as
> well) was what Mike explained in his other email: aliasing access to a JPA
> entity through an interface for the purpose of being able to separate code
> and e.g. have the interfaces in one JAR and the implementation class in
> another one.
>
> > The key part of what was being proposed (at least how I interpreted the
> > feature, Steve can correct me if I misinterpreted) was the ability to
> > "alias" an entity class. This just means that one might be able register
> > an entity class in the providers entity list keyed not only by the
> > concrete entity class, but also an (or more than one?) interface, so
> > that when the provider encounters that interface it gets loaded/saved by
> > the provider as the concrete entity class.
>
>
> No additional metadata, simply metadata aliasing. I think ideas like this
> originate from the trend for developers to build rich domain models, follow
> Domain Driven Design and don't treat domain classes as pure data
> containers. Although one might argue this is not what the JPA spec is about I think
> we should make sure we don't get in the way when following this approach so
> that devs don't get into a "I can't do this because JPA can't deal with
> it" situation from a class' design perspective.
>
> Looking at the extended proposal @Entity on an interface feels a bit weird
> as well, at least given the current semantics in the spec. I could imagine
> an @EntityAlias though with the following usage model:
>
> %<----------------------------------
> @EntityAlias
> public interface Person {
>
> }
>
> @Entity
> public class MyPerson implements Person {
>
> }
> %<----------------------------------
>
> Not sure I favor this over explicitly listing the alias interfaces on the
> @Entity (e.g. @Entity(typeAlias = { Person.class }) as with the original
> proposal you could implement the interface with a second class without
> creating the conflict of two implementation classes using the interface as alias.
>
> Mike Keith wrote:
>
> > Having said that, if we think that aliasing is one of those things that
> > could stop large companies from using JPA we might decide to close our
> > eyes, hold our noses and go ahead and add some kind of support.
>
>
> Could you elaborate on that? I don't quite get why this feature should
> stop companies from using JPA.
>
> > @Entity(alias=Employee.class)
> > public class EmployeeImpl implements Employee {
> > // mappings ...
> > }
> >
> > Where does one draw the line? Would we assume that a single alias is
> > enough and that an entity would not be allowed to specify a Set? For
> > example, that we would not need to support something like:
> >
> > @Entity(aliases={Employee.class, Worker.class}) ... or ...
> > @Entity(aliasInterfaces=true)
> > public class EmployeeImpl implements Employee, Worker {
> > // mappings ...
> > }
>
> The latter doesn't seem to complicate things, does it? At least given the
> assumption there has to be a single implementation class to be selected to
> back the type alias, right?
>
> Cheers,
> Ollie
>
> Am 12.03.2012 um 12:37 schrieb michael keith:
>
> > I would really prefer we not go down this path...
> >
> > -Mike
> >
> > On 12/03/2012 1:31 AM, Matthew Adams wrote:
> >> If we choose to take this on, we could let users express simply
> >> through simple java "implements" statements which persistent
> >> interfaces a given class implements, and we could allow persistent
> >> fields of persistent interface types and persistent collections of
> >> interfaces types, as well as queries through them.
> >>
> >> @Entity
> >> // or @MappedSuperclass?
> >> // or new @EntityInterface?
> >> public interface Employee {
> >>
> >> // default mapping info allowed here?
> >> String getEmployeeNumber();
> >> }
> >> =====
> >> @Entity
> >> public class Person
> >> implements Employee { /* no addl metadata needed -- implements is
> >> sufficient */
> >>
> >> private String employeeNumber;
> >>
> >> @Column(name="emp_num")
> >> public String getEmployeeNumber() { return employeeNumber; }
> >> public String setEmployeeNumber(@NotNull String employeeNumber) {
> >> this.employeeNumber = employeeNumber; }
> >> }
> >> ====
> >> @Entity
> >> public class Corporation {
> >>
> >> @OneToMany
> >> @AllowedClasses({Person.class, Contractor.class})
> >> private List<Employee> employees;
> >>
> >> @OneToOne
> >> @AllowedClasses(Person.class)
> >> private Employee president;
> >>
> >> /* Note:
> >> Any assignment of a class other than those whitelisted in
> >> @AllowedClasses would
> >> cause the JPA implementation to throw ClassCastException
> >> */
> >> }
> >> /*
> >> @AllowedClasses could also be an attribute of relationship annotations
> >> instead of its own annotation.
> >> */
> >> =====
> >>
> >> The hard part, IMHO, is portably mapping them. Wherever you have a
> >> reference to a persistent interface, you also need at the point the
> >> class of the implementation. Further, I would say that persistent
> >> interfaces could only be mapped using property access, as interfaces
> >> have no instance fields.
> >>
> >> One possibility is to allow the use of persistent interfaces, but just
> >> say that their mappings are not portable. It would be a nontrivial
> >> body of work to bite off the additional specification of portably
> >> mapping persistent interfaces.
> >>
> >> -matthew
> >>
> >> On Sun, Mar 11, 2012 at 12:27 PM, michael keith
> >> <michael.keith_at_oracle.com> wrote:
> >>> Let me first say that I don't like the model of interfaces on
> entities. It
> >>> is quite rarely requested and when it is, often the user wants
> multiple
> >>> entities to be able to implement the same interface (e.g. polymorphism
> w/o
> >>> inheritance) to do something like this:
> >>>
> >>> public interface Employee { ... }
> >>> @Entity public class BusEmployee implements Employee { ... }
> >>> @Entity public class TrainEmployee implements Employee { ... }
> >>>
> >>> and then in some entity:
> >>>
> >>> @Entity public class TranportationBureau {
> >>> ...
> >>> @ManyToOne
> >>> Employee empOfTheMonth;
> >>> }
> >>>
> >>> The feature being proposed, if I understood it correctly, would not
> support
> >>> this.
> >>>
> >>> Having said that, if we think that aliasing is one of those things
> that
> >>> could stop large companies from using JPA we might decide to close our
> eyes,
> >>> hold our noses and go ahead and add some kind of support.
> >>>
> >>> While I understood and sympathized with the reasons why Steve first
> >>> suggested that the annotation be on the interface (to facilitate
> >>> interface-to-single-entity enforcement) I tend to agree with Oliver
> and
> >>> Bernd that it would make more sense to just add an "alias" element to
> the
> >>> @Entity annotation and continue to apply it to the impl class. It
> would be
> >>> the responsibility of the provider to disallow two entities from
> creating an
> >>> alias to the same class.
> >>>
> >>> Example:
> >>>
> >>> @Entity(alias=Employee.class)
> >>> public class EmployeeImpl implements Employee {
> >>> // mappings ...
> >>> }
> >>>
> >>> Where does one draw the line? Would we assume that a single alias is
> enough
> >>> and that an entity would not be allowed to specify a Set? For example,
> that
> >>> we would not need to support something like:
> >>>
> >>> @Entity(aliases={Employee.class, Worker.class}) ... or ...
> >>> @Entity(aliasInterfaces=true)
> >>> public class EmployeeImpl implements Employee, Worker {
> >>> // mappings ...
> >>> }
> >>>
> >>> -Mike
> >>>
> >>>
> >>> On 11/03/2012 12:23 PM, Bernd Müller wrote:
> >>>> I think, this would make many things more complex to specify in a
> >>>> consistent way.
> >>>>
> >>>> In general, interfaces are a way to describe contracts in an
> >>>> implementation independent way and therefore should be as abstract
> >>>> as possible. JPA is a mapping between VM-objects and databases and
> >>>> therefore as close as possible to the implementation level.
> >>>> Here I see some problems from a conceptual point of view.
> >>>>
> >>>> I also see many problems in practice. How to map fields in classes,
> >>>> which are eventually named different than the annotated getter in the
> >>>> interface? How to map interface hierarchies with multiple super
> >>>> interfaces to eventually DIFFERENT class hierarchies with
> >>>> single inheritance? There are more, I think.
> >>>>
> >>>> We have to balance if it's worth to get such new problems which have
> to
> >>>> be resolved in the spec and on the other hand the benefit is less
> >>>> typing (how much?).
> >>>>
> >>>>
> >>>> Bernd
> >>>>
> >>>>
> >>>> Am 09.03.2012 19:04, schrieb Steve Ebersole:
> >>>>> I'd like to propose that JPA 2.1 allow @Entity on Java interfaces
> not
> >>>>> just classes. The main reason is typing in spec contracts. For
> domain
> >>>>> models that leverage interfaces, it is usually desirable to deal
> with
> >>>>> the interfaces over the implementation classes. For example, such
> >>>>> applications would generally prefer to attempt to load or get a
> >>>>> reference to an instance based on the interface name as opposed to
> the
> >>>>> class name. E.g.
> >>>>>
> >>>>> public interface Person {
> >>>>> ...
> >>>>> }
> >>>>>
> >>>>> @Entity
> >>>>> public class PersonImpl implements Person {
> >>>>> ...
> >>>>> }
> >>>>>
> >>>>> EntityManager em = ...;
> >>>>> Person p = em.find( Person.class, theKey );
> >>>>>
> >>>>> But this does not work today in a portable manner. To work in the
> most
> >>>>> portable manner, I think the @Entity annotated interface also would
> need
> >>>>> to name the "persistent implementation class":
> >>>>>
> >>>>> @Entity( impl = PersonImpl.class )
> >>>>> public interface Person {
> >>>>> ...
> >>>>> }
> >>>>>
> >>>>> public class PersonImpl implements Person {
> >>>>> ...
> >>>>> }
> >>>>>
> >>>>> It could be up to each provider whether or not to support @Entity on
> an
> >>>>> interface that did not specify a "persistent implementation class".
> >>>>>
> >>>>> Another way to look at this is as basically "aliasing" the entity
> type
> >>>>> metadata using the interface name instead of the implementation
> class
> >>>>> name.
> >>>>>
> >>>>> -Steve
> >>>>
> >>>>
> >>
> >>
>
> --
> /**
> * @author Oliver Gierke - Senior Member Technical Staff
> *
> * @param email ogierke_at_vmware.com
> * @param phone +49-351-30929001
> * @param fax +49-351-418898439
> * @param skype einsdreizehn
> * @see http://www.olivergierke.de
> */
>
--
NEU: FreePhone 3-fach-Flat mit kostenlosem Smartphone!
Jetzt informieren: http://mobile.1und1.de/?ac=OM.PW.PW003K20328T7073a