【问题标题】:Can JPA entity inherit @Version from an interface method?JPA实体可以从接口方法继承@Version吗?
【发布时间】:2013-04-05 13:53:03
【问题描述】:

我定义了一个 Versioned 接口,期望我可以在任何我想使用 JPA 版本控制功能的持久实体上实现它(例如,比较空中碰撞的版本、更新时自动递增)。

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

这并没有节省太多(如果有的话)编码,但它也为我提供了一个我计划稍后使用的标记界面。

public class Foo implements Versioned {
    private int revision;

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

@Version 允许在方法上使用,我希望 Foo 从Versioned 接口继承该特性。情况似乎并非如此。我可以在数据库中更新我的Foo 实例,但修订号不会自动更改。

但是,如果我在实现中添加 @Version 注释,它会按预期工作:

    @Version
    private int revision;

我没有被卡住 - 我可以获得所需的功能。我只是好奇:是否有一个“技巧”可以让它与接口方法上的注释一起正常工作?或者有人可以指出我为什么不能按预期工作的文档吗?

【问题讨论】:

    标签: java inheritance jpa annotations


    【解决方案1】:

    注解继承不适用于方法。来自documentation of @Inherited

    请注意,如果已注释,则此元注释类型无效 type 用于注释除类以外的任何内容。 另请注意,此元注释仅导致注释从超类继承; 已实现接口上的注释无效

    【讨论】:

    • 是的,这看起来就是答案。很有意思。我有点惊讶我以前从未遇到过这种情况。
    • 我认为 \@Inherited 与此无关。 JPA 可以选择在超类和接口中查找注释。如果超类使用 \@MappedSuperclass 注释,它确实如此。不过,它不在接口上。这只是规范做出的选择。
    • @JBNizet,我认为 Isaac 期望注释继承对方法起作用,这就是我给出这个答案的原因。我同意,JPA 可以查看接口。
    • @WilQu 是的,这就是我的预期。正如我在第一条评论中所说,我以前从未遇到过这种怪癖。 JB Nizet,听起来你说这是 JPA 实现可以做的事情,但它不在规范中。
    • 没有。我的意思是,规范说如果使用 MappedSuperclass 进行注释,则在类本身和超类中查找映射注释。而不是在实现的接口中。
    【解决方案2】:

    我很确定这是不可能的。

    首先,因为需要@MappedSuperclass 从超类继承映射注解。所以我不明白为什么映射注释会自动从接口继承。

    其次,如果类中的 JPA 注释是在字段上而不是在 getter 上,那么 getter 上的注释将被忽略。

    规范的第 2.11.2 段说:

    实体可以从提供持久实体状态和映射信息的超类继承, 但它本身并不是一个实体。通常,这种映射超类的目的是定义状态 以及多个实体类共有的映射信息。

    与实体不同,映射的超类是不可查询的,并且不能作为参数传递给 实体管理器 或者 询问 操作。映射超类定义的持久关系必须 是单向的。

    抽象类和具体类都可以指定为映射超类。这 MappedSuper- 班级 注释(或 映射超类 XML 描述符元素)用于指定一个 映射超类。

    (强调我的)

    这是在关于继承的章节中,并且没有关于从接口继承映射的规范。映射只能从抽象类或具体类继承。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-19
      • 2010-10-07
      • 2015-08-02
      • 2020-06-11
      • 2014-10-06
      • 2015-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多