使用JPA覆盖@MappedSuperclass中定义的@Id

时间:2015-04-29 12:01:24

标签: java hibernate jpa hibernate-mapping mappedsuperclass

我有一个AbstractEntity类,它由我的应用程序中的所有实体扩展,基本上充当标识符提供者。

@MappedSuperclass
public class AbstractEntity implements DomainEntity {

    private static final long serialVersionUID = 1L;

    /** This object's id */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected long id;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="creation_date", nullable = false, updatable=false)
    private Date creationDate = new Date();

    /**
     * @return the id
     */
    public long getId() {
        return this.id;
    }

    /**
     * @param id the id to set
     */
    public void setId(long id) {
        this.id = id;
    }
}

我现在有一个案例,我需要为我的几个实体类定义一个单独的Id,因为这些需要有一个自定义的序列生成器。怎么能实现这一目标?

@Entity
@Table(name = "sample_entity")
public class ChildEntity extends AbstractChangeableEntity {

    @Column(name = "batch_priority")
    private int priority;

    public int getPriority() {
        return priority;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }

}

3 个答案:

答案 0 :(得分:5)

你无法做到。如果需要,请查看此GitHub example

在基类中定义@Id后,您无法在子类中覆盖它,这意味着让@Id责任更好每个具体的课程。

查看this article了解详情。

答案 1 :(得分:1)

拆分你的基类。

定义所有常见字段,但ID:

@MappedSuperclass
public  abstract class AbstractEntityNoId implements DomainEntity {
 private static final long serialVersionUID = 1L;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="creation_date", nullable = false, updatable=false)
    private Date creationDate = new Date();
}

使用默认ID生成器扩展上面:

@MappedSuperclass
public abstract class AbstractEntity extends AbstractEntityNoId {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected Long id;

    public Long getId(){
       return id;
    }
}

需要自定义ID生成的类扩展了前者,而其他类扩展了后者。

通过上述内容,除了需要生成自定义ID的实体之外,不需要更改现有代码。

答案 2 :(得分:1)

一种解决方案(在某些情况下不可行)是在get方法上使用批注而不是在字段上。它将为您提供更大的灵活性,特别是可以覆盖您想要的任何内容。

在代码中:

@MappedSuperclass
public class AbstractEntity implements DomainEntity {

    private static final long serialVersionUID = 1L;

    protected long id;

    private Date creationDate = new Date();

    /**
     * @return the id
     */
    /** This object's id */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getId() {
        return this.id;
    }

    /**
     * @param id the id to set
     */
    public void setId(long id) {
        this.id = id;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="creation_date", nullable = false, updatable=false)
    public Date getCreationDate () {
        return this.creationDate ;
    }
}

以及您的子类:

@Entity
@Table(name = "sample_entity")
public class ChildEntity extends AbstractChangeableEntity {


private int priority;

@Override
@Id
@GeneratedValue(strategy = GenerationType.ANOTHER_STRATEGY)
public long getId() {
    return this.id;
}

@Column(name = "batch_priority")
public int getPriority() {
        return priority;
    }
public void setPriority(int priority) {
        this.priority = priority;
    }

}