On Jul 7, 2008, at 11:35 AM, Rick McGuire wrote:

Dain Sundstrom wrote:
On Jul 7, 2008, at 10:29 AM, Rick McGuire wrote:

Dain Sundstrom wrote:
On Jun 27, 2008, at 11:57 AM, David Blevins wrote:

[psst, update your openejb-dev mail alias, it's still using [EMAIL PROTECTED] ]
On Jun 27, 2008, at 6:33 AM, Rick McGuire wrote:

I've been trying to understand and document how the CMP-JPA integration works, and I've found something in the CMP2 code that has me confused. In the mapClass2X() method in CmpJmpConversion, the code derives the names of the CMP field mappings by looking for abstract "get" and "is" methods in the bean class. However, in the createGetter() method in Cmp2Generator, the getter name is always generated using a "get" prefix. Shouldn't this be checking to see if the abstract method is an "is" method and generate the appropriate one? The current code would appear to generate a non- instantiable class if the source bean is using "is" methods.

I added the "is" logic in there and I'm not sure at all if it is compliant. I guess that'd be the first question. Second one might be, if we do it anyway, will it mess up JPA? If the answers are yes and no respectively, we definitely should. If the answers are no and no, then we still could if we wanted to add it as an extra feature.

In CMP-JPA, we configure JPA not use the getters or setters, but instead it accesses the field directly. The main reason for this is because the CMR getter/setter is defined in terms of the EJB local interface which JPA doesn't understand.
Dain, could you elaborate on why it's necessary to use field level access? I'm not sure I understand the significance of the EJB local interface comment.

In CMP the CMR fields are defined in terms of the EJB Local interface. For example, in an Order-LineItems relations the LineItems field on the Order class will be defined as follows:

   Collection<LineItemsLocal> getLineItems();
   void getLineItems(Collection<LineItemsLocal> newLineItems);

Whereas in JPA, the relationship filed is defined in terms of the Object class itself, since JPA doesn't know anything about interfaces. In the case of Order-LineItems again, the property accessor declaration is as follows:

   Collection<LineItems> getLineItems() { ... }
   void getLineItems(Collection<LineItems> newLineItems) { ... }

This means we can't let JPA use the abstract CMR getter and setters and instead need to point JPA at a field or property defined in terms of the instance class (and specifically not the EJB local interface).

In the generated implementation of the CMR getter and setters, we wrap the real JPA collection object with one that wrappers the raw EJB instance with a local interface proxy when an instance is returned, and we unwrapper an instance added to the collection.

It would be a lot simpler if JPA had proxying support, but it doesn't look like it is coming in the next spec version.
Ok, I think I understand. Shouldn't it be possible (and more efficient) to allow JPA to use the getters and setters if there are no CMR fields? Or does JPA require all one style?

I've been hacking on JaxB lately, so I had to look this up in the spec.

EJB-Persistence 3.0 section 2.1.1
The persistent state of an entity is accessed by the persistence provider runtime[1] either via JavaBeans style property accessors or via instance variables. A single access type (field or property access) applies
to an entity hierarchy.

Also, my guess is that property based persistence is slightly slower then field based. This is because when a bean is loaded the JPA provider must call the setter method before a getter is called. Field interception will be slightly more efficient since the setter method is not invoked.

-dain


Reply via email to