Подтвердить что ты не робот

Как переопределить стратегию GenerationType с помощью аннотаций Hibernate/JPA?

Я рассматриваю использование аннотаций для определения своих сопоставлений Hibernate, но столкнулся с проблемой: я хочу использовать базовый класс сущности для определения общих полей (включая поле 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();
}
4b9b3361

Ответ 1

В приведенном выше коде, похоже, вы смешиваете аннотации по полям (суперкласс) и методам (подкласс). Справочная документация Hibernate

Как решение вашей проблемы, я рекомендую удалить поле id из базового суперкласса. Вместо этого переместите это поле в подклассы и создайте в своем базовом классе методы getId() и setId(). Затем переопределите/реализуйте методы getId() и setId() в ваших подклассах и аннотируйте геттеры с желаемой стратегией генерации.

Надеюсь, что это поможет.

Ответ 2

В методе в child не добавляем второй тег @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 и определите его.

Ответ 4

Если вы помещаете свои аннотации на геттер, а не на поле, когда вы переопределяете метод в подклассе, то аннотации, размещенные там, будут использоваться, а не те, что находятся в суперклассе.