[hibernate-dev] Another @Access quandry

Steve Ebersole steve at hibernate.org
Wed Mar 26 11:12:40 EDT 2014


It does violate the spec though, that's the problem:

"... It is not permitted to specify a field as Access(PROPERTY) or a
property as Access(FIELD)..."

which imo is exactly what this is doing (specifying a property as FIELD):

    @Id
    @GeneratedValue
    @Access(AccessType.FIELD)
    public long getId() {
        return id;
    }



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

> I do of course agree that people should use a single strategy and
> stick to it, so I agree with your reading about what the "general
> expectation" is.
>
> But the original test represents a quite naturally looking example and
> it's hard to justify why that should be considered illegal; I'd
> probably be more inclined in making user's life easier than try to
> lecture them about how a proper mapping should look like.
>
> Ignoring any annotation leads to waste of time and debugging
> frustration, so rather than silently discarding a mis-positioned
> annotation I'd prefer a fail-fast approach; that said I think just
> applying them all - as long as there are no obvious conflicting
> annotations - would be even more user friendly and doesn't seem to
> violate any specific wording of the spec.
>
> Sanne
>
>
> On 26 March 2014 13:57, Steve Ebersole <steve at hibernate.org> wrote:
> > Again from the spec (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".
> >
> > Which to me implies that the expectation for switching access for a
> > particular field within such a class is to annotate the *field* with
> > Access(FIELD).
> >
> > Also the footnote to this sections seems very relevant:
> >
> > "[8] ... It is not permitted to specify a field as Access(PROPERTY) or a
> > property as Access(FIELD)..."
> >
> >
> >
> > On Wed, Mar 26, 2014 at 8:02 AM, Emmanuel Bernard <
> emmanuel at hibernate.org>
> > wrote:
> >>
> >> My reading at the time and what I did find more intuitive is what the
> >> test represents.
> >>
> >> Entity level @AccessType expresses where the annotations should
> >> be. Otherwise the position of @Id is used to find the access type to
> >> consider annotation wise.
> >>
> >> If for a few attributes I wish to use the alternative property access, I
> >> can add @AccessType next to the other annotations but expressing that
> >> the actual property value access is based on the alternative access.
> >> That way, all annotations are in the same place.
> >>
> >> On Wed 2014-03-26 11:12, Sanne Grinovero 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
> >> > _______________________________________________
> >> > 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