jsr338-experts@jpa-spec.java.net

[jsr338-experts] Re: proposal : _at_Entity on interfaces

From: Pinaki Poddar <ppoddar_at_us.ibm.com>
Date: Mon, 12 Mar 2012 09:44:45 -0700

>> Let me first say that I don't like the model of interfaces on entities.
++1

The notion of interface in Java and type that has persistent state just do
not mix.
The "contract:" of interface is not a state-oriented contract.
Trying to mix them will not be a step in a right direction.


Regards --

Pinaki Poddar
Chair, Apache OpenJPA Project http://openjpa.apache.org/
JPA Expert Group Member
Application & Integration Middleware








From: michael keith <michael.keith_at_oracle.com>
To: jsr338-experts_at_jpa-spec.java.net
Cc: Matthew Adams <matthew_at_matthewadams.me>, Bernd Müller
            <bernd.mueller_at_ostfalia.de>
Date: 03/12/2012 04:39 AM
Subject: [jsr338-experts] Re: proposal : @Entity on interfaces



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