Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] Using constructor injection with JPA entities

I am more concerned about JPA (all implementations) than just EclipseLink in
this case. In either case, I don't think that a private constructor can be
used because CGLIB proxies need to know what superclass constructor to
invoke. It is my understanding that all JPA 1.0 implementations (including
EclipseLink) require a protected default constructor for this reason.

It is also worth nothing that one of the reasons I want constructor-based
injection is so I can centralize all my validation code in a single method.
If you use the default constructor and inject values directly into the
fields it essentially defeats the point.

We need *real* constructor injection.

The way I would implement it is:

1) Generate a list of all persistent fields (basically anything not marked
using @Transient)
2) Either inject the fields using the JPA 1.0 approach (default constructor
and setter methods), or
3) Inject the fields using constructor injection. Match the field value to
the constructor parameter either by its type or using @Named.

I'm wondering if this is technically doable. I've already thought of the
following potential problem:

EntityManager.refresh(Object) does not return an object. Technically
speaking this shouldn't be a problem because refresh(immutable) should be a
no-op but if someone *does* modify the database directly then this method
would need to throw an exception indicating that a change has occurred but
cannot be applied because the object is marked as immutable. Alternatively,
you could add refresh() that returns a new Object.

Gili


James Sutherland wrote:
> 
> I think that the default constructor you provide JPA can be marked
> private, so would be ok.  If a private constructor does not work in
> EclipseLink, please log a bug.  EclipseLink also has support for an
> InstantiationPolicy that can use a private static method, or factory.
> 
> 
> cowwoc wrote:
>> 
>> But you cannot use constructor injection in JPA 1.0, it still forces you
>> to provide a default constructor.
>> 
>> Gili
>> 
>> 
>> James Sutherland wrote:
>>> 
>>> JPA 1.0 supports field access, so you do not need set methods if you use
>>> field access, which is normally the better way to go anyway.
>>> 
>>> 
>>> cowwoc wrote:
>>>> 
>>>> Hi,
>>>> 
>>>> I am curious whether it conceivably possible for JPA 2.0 to add support
>>>> for constructor injection for such things as read-only entities. I'm
>>>> not a fan of the JavaBean design pattern and I'm wondering whether it
>>>> would be possible to move EclipseLink and JPA closer to the Guice way
>>>> of doing things. For example:
>>>> 
>>>> class Foo
>>>> {
>>>>   public Foo(@Named("username") String username, @Named("password")
>>>> String password)
>>>>   {}
>>>> 
>>>>   // mapping annotations go on getters
>>>>   public String getUsername() {}
>>>>   public String getPassword() {}
>>>> 
>>>>   // no setters
>>>> }
>>>> 
>>>> It would be even better if you could pick up the property names
>>>> directly from the variable name but I believe there are technical
>>>> problems with that approach.
>>>> 
>>>> Thank you,
>>>> Gili
>>>> 
>>> 
>>> 
>> 
>> 
> 
> 

-- 
View this message in context: http://www.nabble.com/Using-constructor-injection-with-JPA-entities-tp21335376p21417156.html
Sent from the EclipseLink - Users mailing list archive at Nabble.com.



Back to the top