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

2022-09-01 14:08:30

我正在为两个不同的表创建相同的实体。为了使表映射等对于两个实体有所不同,但只有其余的代码在一个地方 - 一个抽象的超类。最好的办法是能够在超类中注释泛型内容,例如列名(因为列名是相同的),但这不起作用,因为子类不继承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;

}

有什么想法,或者我是否必须在子类中创建字段,getters和setter?

谢谢,克里斯


答案 1

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


答案 2

下面是一个示例,其中包含一些可能有帮助的解释。

@MappedSuperclass:

  • 是方便类
  • 用于存储子类可用的共享状态和行为
  • 不可持久
  • 只有子类是持久的

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

  1. 单桌
  2. 加入
  3. 每类的表

@DiscriminatorColumn用于定义将使用哪个列来区分子对象。

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

下面的代码产生以下结果:

enter image description here

您可以看到 id 字段位于两个表中,但仅在抽象实体 Id @MappedSuperclass中指定。

此外,@DisciminatorColumn在“缔约方”表中显示为PARTY_TYPE。

@DiscriminatorValue在“参与方”表的“PARTY_TYPE”列中显示为“人员”作为记录。

非常重要的是,抽象实体 Id 类根本不会持久化。

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

如果您添加了扩展参与方的组织实体,并且接下来保留该实体,则“参与方”表将具有:

  • 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.

    }

希望这有助于:)


推荐