[hibernate-dev] Another @Access quandry

Sanne Grinovero sanne at hibernate.org
Wed Mar 26 07:12:33 EDT 2014


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