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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/328202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 11:58:47  来源:igfitidea点击:

How do I override the GenerationType strategy using Hibernate/JPA annotations?

javahibernatejpaannotations

提问by Adrian Pronk

I'm considering using Annotations to define my Hibernate mappings but have run into a problem: I want to use a base entity class to define common fields (including the ID field) but I want different tables to have different ID generation strategies:

我正在考虑使用 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?
    ...
}

Is there some way to do this? I've tried including the following into TableBbut hibernate objected to my having the same column twice and it seems wrong:

有没有办法做到这一点?我试过将以下内容包含在内,TableB但 hibernate 反对我两次使用同一列,这似乎是错误的:

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

采纳答案by David Crow

In the code above, it looks like you're mixing annotations on fields (superclass) and methods (subclass). The Hibernate reference documentationrecommends avoiding this, and I suspect it might be causing the problem. In my experience with Hibernate, it's safer and more flexible to annotate getter/setter methods instead of fields anyway, so I suggest sticking to that design if you can.

在上面的代码中,看起来您在字段(超类)和方法(子类)上混合了注释。Hibernate参考文档建议避免这种情况,我怀疑它可能会导致问题。根据我使用 Hibernate 的经验,无论如何注释 getter/setter 方法而不是字段更安全、更灵活,所以我建议如果可以的话坚持这种设计。

As a solution to your problem, I recommend removing the idfield from your Base superclass altogether. Instead, move that field into the subclasses, and create abstract getId()and setId()methods in your Base class. Then override/implement the getId()and setId()methods in your subclasses and annotate the getters with the desired generation strategy.

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

Hope this helps.

希望这可以帮助。

回答by LenW

On the method in the child dont add the second @Id tag.

在孩子的方法上不要添加第二个@Id 标签。

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

回答by Xiè Jìléi

My resolution:

我的决心:

Refactor the Baseclass into:

Base类重构为:

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

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

Then, you can extends from Base for most of your entity classes, and if one needs to override the @GeneratedValue, just extend from SuperBaseand define it.

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

回答by osi

If you put your annotations on the getter rather than the field, when you override the method in the subclass, the annotations placed there will be used rather than the ones in the superclass.

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