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

12

我在考虑使用注释来定义我的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个回答

5
在上面的代码中,看起来你正在混合使用字段注释(在超类中)和方法注释(在子类中)。Hibernate 参考文档 建议避免这样做,而且我怀疑它可能会导致问题。根据我使用Hibernate的经验,安全且更灵活的方法是注释getter/setter方法而不是字段,因此如果可以的话,建议坚持这种设计。
作为解决办法,我建议从你的Base超类中彻底删除id字段,而是将该字段移到子类中,并在Base类中创建抽象的getId()和setId()方法。然后在你的子类中覆盖/实现getId()和setId()方法,并使用期望的生成策略注释getter方法。
希望这有所帮助。

4
在子类的方法中不要添加第二个 @Id 标记。
@Override // So that we can set Generated strategy
@GeneratedValue(strategy = AUTO)
public Integer getId() {
    return super.getId();
}

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扩展并定义它。


1
如果您将注释放在getter而不是字段上,当您在子类中覆盖该方法时,放置在那里的注释将被使用,而不是超类中的注释。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接