简体   繁体   中英

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

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:

@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 TableB but hibernate objected to my having the same column twice and it seems wrong:

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

In the code above, it looks like you're mixing annotations on fields (superclass) and methods (subclass). The Hibernate reference documentation recommends 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.

As a solution to your problem, I recommend removing the id field 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.

Hope this helps.

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

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

My resolution:

Refactor the Base class into:

@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 SuperBase and define it.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM