Hi Laird,
I don't know all of this history with this, but my guess is that this
"final" restriction is due to the JPA Providers that monitor persistence
activities by creating subclasses of the Entity classes. It's not due to
the bytecode injection since that should still be doable even if the
classes or methods are marked "final". Although most JPA Providers do
bytecode injection of some type for performance reasons, I believe there
are still JPA implementations that rely on subclassing. If not as their
primary "entity enhancement mechanism", at least as their secondary
mechanism.
At this point, I would say it would be up to each JPA provider to
determine whether they want to allow these "final" entity classes or
methods. Of course, this practice may not be portable to other JPA
providers. This would be just another feature that one JPA provider would
have over another... For example. OpenJPA's documentation [1] states
that they support final classes and methods. But, my guess is that this
statement only applies to their bytecode enhancement mechanism (preferred)
and not their secondary subclassing support.
-- Kevin Sutter
[1]
http://ci.apache.org/projects/openjpa/trunk/docbook/manual.html#jpa_overview_pc_final
From: Laird Nelson <ljnelson_at_gmail.com>
To: users_at_jpa-spec.java.net,
Date: 12/16/2013 05:30 PM
Subject: [jpa-spec users] finality: prohibited for ALL methods of
all kinds in entity classes?
The JPA 2.1 specification says:
The entity class must not be final. No methods or persistent instance
variables of the entity class may be final.
Does "no methods" mean every single method—private, static, protected,
non-state-changing, etc.—in the entity class? Or was this supposed to
convey that only methods annotated with @Access(AccessType.PROPERTY) are
prohibited from being final?
I understand why entity classes cannot be final, and I understand why
persistent instance variables of the entity class cannot be final. I also
understand why persistent property accessors and mutators cannot be final.
I don't understand why all other methods (ones that manipulate transient
fields, for example, or that are stateless) cannot be final.
The best I can surmise is that the specification wanted to leave the door
open for bytecode injection everywhere—e.g. perhaps my stateless method's
invocation of a getter needs to have that invocation be rewritten to
invoke some kind of JPA-provider-injected method instead.
This makes it hard to reuse entity-like classes From Elsewhere as building
blocks, since some of them may feature final methods, but are in every
other way suitable for augmenting with an orm.xml and thereby for
transforming into JPA entities.
Any help appreciated. In the meantime, I'll adhere to the letter of the
specification.
Best,
Laird
--
http://about.me/lairdnelson