是否可以将JPA注释添加到超类实例变量中?

时间:2010-05-21 14:41:50

标签: java inheritance jpa annotations

我正在为两个不同的表创建相同的实体。为了使两个实体的表映射等不同,但只将其余的代码放在一个地方 - 一个抽象的超类。最好的方法是能够在超类中注释诸如列名之类的通用内容(因为它们将是相同的),但这不起作用,因为JPA注释不是由子类继承的。这是一个例子:

public abstract class MyAbstractEntity {

  @Column(name="PROPERTY") //This will not be inherited and is therefore useless here
  protected String property;


  public String getProperty() {
    return this.property;
  }

  //setters, hashCode, equals etc. methods
}

我想继承并仅指定特定于孩子的内容,例如注释:

@Entity
@Table(name="MY_ENTITY_TABLE")
public class MyEntity extends MyAbstractEntity {

  //This will not work since this field does not override the super class field, thus the setters and getters break.
  @Column(name="PROPERTY") 
  protected String property;

}

我是否需要在子类中创建字段,getter和setter?

谢谢, 克里斯

4 个答案:

答案 0 :(得分:26)

您可能希望使用@MappedSuperclass类注释MyAbstractEntity,以便hibernate将在子项中导入MyAbstractEntity的配置,您不必覆盖该字段,只需使用父项。该注释是休眠的信号,它必须检查父类。否则它假定它可以忽略它。

答案 1 :(得分:13)

以下是一些可能有所帮助的解释示例。

@MappedSuperclass:

  • 是一个便利课
  • 用于存储共享状态&儿童类可用的行为
  • 不能坚持
  • 只有子课程可以保留

@Inheritance指定三种映射策略之一:

  1. 单表
  2. 加入
  3. 每班表
  4. @DiscriminatorColumn用于定义将用于区分子对象的列。

    @DiscriminatorValue用于指定用于区分子对象的值。

    以下代码会产生以下结果:

    enter image description here

    您可以看到id字段在两个表中,但仅在AbstractEntityId @MappedSuperclass中指定。

    此外,@ DiscisatorColumn在Party表中显示为PARTY_TYPE。

    @DiscriminatorValue在Party表的PARTY_TYPE列中显示为Person作为记录。

    非常重要的是,AbstractEntityId类根本没有持久化。

    我没有指定@Column注释,而只是依赖于默认值。

    如果您添加了一个扩展Party的组织实体,并且如果该组织实体接下来一直存在,那么Party表将具有:

    • id = 2
    • PARTY_TYPE =“组织”

    组织表第一个条目将具有:

    • id = 2
    • 与组织具体相关的其他属性值
    
        @MappedSuperclass
        @SequenceGenerator(name = "sequenceGenerator", 
                initialValue = 1, allocationSize = 1)
        public class AbstractEntityId implements Serializable {
    
            private static final long serialVersionUID = 1L;
    
            @Id
            @GeneratedValue(generator = "sequenceGenerator")
            protected Long id;
    
            public AbstractEntityId() {}
    
            public Long getId() {
                return id;
            }
        }
    
        @Entity
        @Inheritance(strategy = InheritanceType.JOINED)
        @DiscriminatorColumn(name = "PARTY_TYPE", 
                discriminatorType = DiscriminatorType.STRING)
        public class Party extends AbstractEntityId {
    
            public Party() {}
    
        }
    
        @Entity
        @DiscriminatorValue("Person")
        public class Person extends Party {
    
            private String givenName;
            private String familyName;
            private String preferredName;
            @Temporal(TemporalType.DATE)
            private Date dateOfBirth;
            private String gender;
    
            public Person() {}
    
            // getter & setters etc.
    
        }
    
    

    希望这会有所帮助:)

答案 2 :(得分:3)

将超类标记为

@MappedSuperclass

并从子类中删除该属性。

答案 3 :(得分:2)

使用@MappedSuperclass注释您的基类应该完全符合您的要求。