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
>>>
>>>
>
>