[hibernate-dev] Another @Access quandry

Steve Ebersole steve at hibernate.org
Wed Mar 26 09:53:11 EDT 2014


I think you are misreading the use of the term "may" there to mean that
annotations could be placed on the field or on the getter.  I read it to
mean that that "may" be placed on the getter, or not (remember many
attributes do not require annotations be present).

I personally think it makes no sense to mix placement of annotations for a
given attribute.  When you say "The @Access property would then only be
used to state which access strategy should be used (and a nice effect is
tha the name becomes particularly self-explanatory too)", I think you are
making an assumption about the meaning of the terms "access" and "access
type" that the spec simply does not consistently back.  In fact the very
next sentence after what I quoted says (still discussing class-level
Access(PROPERTY)) : "The behavior is undefined if mapping annotations are
placed on any instance variables defined by the class for which
Access(FIELD) is not specified".  Granted the spec says the behavior is
undefined, so we are free to support that if we want.  However, it is
clearly not the intended behavior.


As I have brought up on the list a few times now recently, the notion of
"access" is really 2-fold in terms of identifying:
1) where to look for annotations at binding time
2) how to extract value from and inject value into the attribute at runtime

It is just so odd in retrospect that the spec never says plainly "The
AccessType determined for an attribute indicates how that attribute is
accessed by the persistence provider at runtime in terms of extracting and
injecting values...".  You make that argument, but actually the spec never
says that.



On Wed, Mar 26, 2014 at 6:12 AM, Sanne Grinovero <sanne at hibernate.org>wrote:

> As a user I would not expect the @Access annotation to be treated as a
> special case by the framework in terms of when an annotation is
> ignored, as for example that I can put this on either properties or
> fields, and it would not be ignored, while other annotations could be
> ignored depending on the position.
>
> Also I highly doubt that there is a practical use case to "comment" a
> mapping annotation by moving it to the wrong position (say I move a
> @GeneratedValue from a field to a property when using FIELD access):
> that would be extremely confusing to maintain.
>
> The spec's wording states "When Access(PROPERTY) is applied to an
> [...] mapping annotations **may** be placed on .."
> I'd stress that it doesn' t say "must" but "may", and also doesn't
> seem to strictly ban the opposite.
>
> As a user if I put a mapping annotation anywhere I expect it to be
> respected, so I would expect the framework to work on the union of the
> possible positions, and probably even to throw an exception on
> conflicting options. The @Access property would then only be used to
> state which access strategy should be used (and a nice effect is tha
> the name becomes particularly self-explanatory too).
>
> Also there are many types of possible contradictions in the mapping
> options:
>
> public class Course {
>     @Id @GeneratedValue(strategy=TABLE)
>     private long id;
>     ...
>
>     @Id @GeneratedValue(strategy=SEQUENCE)
>     public long getId() {
>         return id;
>     }
>
> Or you could have a stronger conflict which isn't solvable via
> AccesType "rules" either:
>
> public class Course {
>     @Id @GeneratedValue(strategy=TABLE)
>     @Access(AccessType.FIELD)
>     private long id;
>     ...
>
>     @Id @GeneratedValue(strategy=SEQUENCE)
>     @Access(AccessType.PROPERTY)
>     public long getId() {
>         return id;
>     }
>
> This last example is the reason why I think you should always
> consistently look at both to collect mapping options, and possibly
> throw runtime exceptions.
>
> Sanne
>
>
>
>
> On 26 March 2014 04:13, Steve Ebersole <steve at hibernate.org> wrote:
> > >From the test
> >
> org.hibernate.test.annotations.access.jpa.AccessMappingTest#testExplicitPropertyAccessAnnotationsWithHibernateStyleOverride
> > we have the following:
> >
> >
> > @Entity
> > @Access(AccessType.PROPERTY)
> > public class Course3 {
> >     private long id;
> >     ...
> >
> >     @Id
> >     @GeneratedValue
> >     @Access(AccessType.FIELD)
> >     public long getId() {
> >         return id;
> >     }
> >     ...
> > }
> >
> > The test asserts that this is a valid mapping.  Granted that the spec is
> > very unclear here, so I might be missing something.  The pertinent spec
> > section here states:
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > *<quote>When Access(PROPERTY) is applied to an entity class, mapped
> > superclass, or embeddableclass, mapping annotations may be placed on the
> > properties of that class, and the persistenceprovider runtime accesses
> > persistent state via the properties defined by that class. All
> proper-ties
> > that are not annotated with the Transient annotation are persistent.
> > WhenAccess(PROPERTY) is applied to such a class, it is possible to
> > selectively designate indi-vidual attributes within the class for
> instance
> > variable access. To specify a persistent instancevariable for access by
> the
> > persistence provider runtime, that instance variable must be desig-nated
> > Access(FIELD).</quote>*
> >
> >
> > I can see a few different ways to read that:
> >
> > 1) @Access can be placed on the attribute to define both where to look
> for
> > mapping annotations and the runtime access strategy for a given
> attribute.
> >  Here, we'd do:
> >
> > @Entity
> > @Access(AccessType.PROPERTY)
> > public class Course3 {
> >     @Id
> >     @GeneratedValue
> >     @Access(AccessType.FIELD)
> >     private long id;
> >     ...
> >
> >     public long getId() {
> >         return id;
> >     }
> >     ...
> > }
> >
> > 2) @Access can be placed on the attribute to define the runtime access
> > strategy for a given attribute, but the class/hierarchy AccessType
> controls
> > where to look for mapping annotations.  This would lead to:
> >
> > @Entity
> > @Access(AccessType.PROPERTY)
> > public class Course3 {
> >     @Access(AccessType.FIELD)
> >     private long id;
> >     ...
> >
> >     @Id
> >     @GeneratedValue
> >     public long getId() {
> >         return id;
> >     }
> >     ...
> > }
> >
> > The test seems to illustrate that our legacy code made yet a 3rd reading
> of
> > this passage such that @Access is still considered a "mapping annotation"
> > even though that seems to directly contradict "To specify a persistent
> > instance
> > variable for access by the persistence provider runtime, that instance
> > variable must be desig-
> > nated Access(FIELD)."
> >
> >
> > Is there some other passage I am missing that bears on what to do here?
> >  How do y'all feel about that passage and its implications on this test
> > mapping?
> > _______________________________________________
> > hibernate-dev mailing list
> > hibernate-dev at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/hibernate-dev
>


More information about the hibernate-dev mailing list