Как переопределить стратегию GenerationType с использованием аннотаций Hibernate / JPA? - PullRequest
12 голосов
/ 30 ноября 2008

Я рассматриваю возможность использования аннотаций для определения моих отображений Hibernate, но столкнулся с проблемой: я хочу использовать базовый класс сущностей для определения общих полей (включая поле идентификатора), но я хочу, чтобы разные таблицы имели разные стратегии генерации идентификаторов :

@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 ]

4 голосов
/ 30 ноября 2008

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

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

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

3 голосов
/ 25 апреля 2011

Мое разрешение:

Преобразовать класс 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 голосов
/ 04 декабря 2008

В методе child не добавляйте второй тег @Id.

@Override // So that we can set Generated strategy
@GeneratedValue(strategy = AUTO)
public Integer getId() {
    return super.getId();
}
1 голос
/ 10 января 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...