如何使用Hibernate / JPA注释覆盖GenerationType策略?

时间:2008-11-29 23:46:26

标签: java hibernate jpa annotations

我正在考虑使用Annotations来定义我的Hibernate映射但遇到了一个问题:我想使用基本实体类来定义公共字段(包括ID字段)但我希望不同的表具有不同的ID生成策略:

@MappedSuperclass
public abstract class Base implements Serializable {
    @Id
    @Column(name="ID", nullable = false)
    private Integer id;
    public Integer getId(){return id;}
    public void setId(Integer id){this.id = id;}
    ...
}

@Entity
@Table(name="TABLE_A")
public class TableA extends Base {
    // Table_A wants to set an application-defined value for ID
    ...
}

@Entity
@Table(name="TABLE_B")
public class TableB extends Base {
    // How do I specify @GeneratedValue(strategy = AUTO) for ID here?
    ...
}

有没有办法做到这一点?我已经尝试将以下内容包含在TableB中,但是hibernate反对我两次使用相同的列并且它似乎错了:

@Override // So that we can set Generated strategy
@Id
@GeneratedValue(strategy = AUTO)
public Integer getId() {
    return super.getId();
}

4 个答案:

答案 0 :(得分:4)

在上面的代码中,看起来你正在混合字段(超类)和方法(子类)上的注释。 Hibernate reference documentation建议避免这种情况,我怀疑它可能导致问题。根据我对Hibernate的体验,无论如何都要更加安全,更灵活地注释getter / setter方法而不是字段,所以如果可以,我建议坚持使用该设计。

作为问题的解决方案,我建议您完全删除Base超类中的 id 字段。而是将该字段移动到子类中,并在Base类中创建抽象的 getId() setId()方法。然后覆盖/实现子类中的 getId() setId()方法,并使用所需的生成策略注释getter。

希望这有帮助。

答案 1 :(得分:3)

关于孩子的方法,不要添加第二个@Id标签。

@Override // So that we can set Generated strategy
@GeneratedValue(strategy = AUTO)
public Integer getId() {
    return super.getId();
}

答案 2 :(得分:3)

我的决议:

Base类重构为:

@MappedSuperclass
abstract class SuperBase<K> {
    public abstract K getId();
}

@MappedSuperclass
class Base<K> extends SuperBase<K> {
    @Id @GeneratedValue(AUTO)
    public K getId() { ... }
}

然后,您可以从Base扩展到大多数实体类,如果需要覆盖@GeneratedValue,只需从SuperBase扩展并定义它。

答案 3 :(得分:1)

如果将注释放在getter而不是字段上,当重写子类中的方法时,将使用放在那里的注释而不是超类中的注释。