简体   繁体   中英

Can JPA entity inherit @Version from an interface method?

I defined a Versioned interface, expecting that I could implement it on any persisted entity that I wanted to use the JPA versioning features (eg, comparing version for mid-air collisions, auto-incrementing on updates).

public interface Versioned {
    @Version
    int getRevision();
}

This doesn't save much (if any) coding, but it also gives me a marker interface that I had plans for later.

public class Foo implements Versioned {
    private int revision;

    @Override
    public int getRevision() {
            return revision;
    }
}

@Version is allowed on methods, and I expected Foo to inherit that characteristic from the Versioned interface. That does not appear to be the case. I can update my instance of Foo in the database, but the revision number doesn't change automatically.

If, however, I add a @Version annotation to the implementation, it works as expected:

    @Version
    private int revision;

I'm not stuck - I can get the functionality I need. I'm just curious: is there a "trick" to getting this to work properly with the annotation on the interface's method? Or can someone point me to documentation of why this doesn't work as I expect?

Annotation inheritance doesn't work on methods. From the documentation of @Inherited :

Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect .

I'm pretty sure this isn't possible.

First of all, because @MappedSuperclass is needed to inherit mapping annotations from a superclass. So I don't see why mapping annotations would automatically be inherited from an interface.

Second because if the JPA anotations in the class are on fields and not on getters, the annotations on getters will be ignored.

Paragraph 2.11.2 of the spec says:

An entity may inherit from a superclass that provides persistent entity state and mapping information, but which is not itself an entity. Typically, the purpose of such a mapped superclass is to define state and mapping information that is common to multiple entity classes.

A mapped superclass, unlike an entity, is not queryable and must not be passed as an argument to EntityManager or Query operations. Persistent relationships defined by a mapped superclass must be unidirectional.

Both abstract and concrete classes may be specified as mapped superclasses . The MappedSuper- class annotation (or mapped-superclass XML descriptor element) is used to designate a mapped superclass.

(emphasis mine)

This is in the chapter about inheritance, and nowhere does the spec talsk about inherited mapping from interfaces. Mapping can only be inherited from abstract or concrete classes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM