Какво е правилното картографиране на JPA за @Id в родител и уникална последователност в базови класове

Имам йерархия на класове:

abstract DomainObject {
...
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="SEQ")
    @SequenceGenerator(name="SEQ",sequenceName="SEQ_DB_NAME")
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;
...
}

BaseClass extends DomainObject {
...
   // Fill in blank here where this class's @Id will use a unique sequence generator
   // bonus points for any sort of automatic assignment of generator names that might 
   //prevent me from having to instrument all my domain objects uniquely
...
}

бележки:

  • Не се нуждая конкретно от генератор на базов клас, така че ако трябва да го премахна, няма проблем.
  • Това е oracle 9i db, ако това е приложимо
  • Хибернация 3.4 JPA
  • Предлага се и Spring 2.5

Благодаря


person Nathan Feger    schedule 23.06.2009    source източник


Отговори (2)


Добре, ето как в крайна сметка реших проблема:

Базов клас:

@MappedSuperclass
public abstract class DomainObject implements Serializable {
 @Id
 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="SEQ")
 @Column(name = "id", updatable = false, nullable = false)
 private Long id;

 .. rest of class
}

Клас потомък:

@Entity
@SequenceGenerator(name="SEQ",sequenceName="SEQ_DB_NAME")
public class BusinessObject extends DomainObject {

 ...

}
person Nathan Feger    schedule 24.11.2009
comment
Вярвам, че това ще работи само за първото ви разширение на DomainObject в рамките на същата единица за постоянство. На следващия, където трябва да зададете името на SequenceGenerator също да бъде SEQ, това ще се провали. Поне това направи моят, използвайки доставчика на EclipseLink JPA и според javadoc download.oracle.com/javaee/5/api/javax/persistence/ името трябва да е уникално. - person digitaljoel; 31.10.2010
comment
за всеки друг, който гледа тази тема...този коментар е случаят за OpenJPA 2.2. Не можете да претоварвате името на SequenceGenerator. - person DAJ; 30.08.2013

Бих ви препоръчал да използвате типа наследяване JOINED за базовия клас. Това поставя всички общи полета в основната таблица и персонализациите в конкретни таблици. Ето анотацията за това:

@Inheritance(strategy=InheritanceType.JOINED)

След като това стане, можете почти да използвате всяка опция за последователност, тъй като всичките ви идентификатори винаги са на една и съща таблица. Можете да използвате отделна последователност, ако желаете, но тя не се поддържа от всички доставчици на бази данни. Предполагам, че това не е проблем, тъй като използвате конкретно Oracle.

Използвал съм това и изглежда, че работи добре.

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
person Chris Dail    schedule 23.06.2009
comment
Донякъде е трудно да се каже какво е било намерението на Нейтън от примера, но се натъкнах на този въпрос, защото мигрирам от съпоставяния на Hibernate към JPA анотации и всичките ми обекти разширяват базов клас, така че не трябва да дефинирам поле за идентификатор , getter/setter, equals(), hashCode() и т.н. за всеки клас, който искам да запазя. В моя случай използвам наследяване, за да намаля шаблонния код, но всъщност няма никакво наследяване от гледна точка на данните. В такъв случай @MappedSuperclass наистина би било предпочитаното решение. - person spaaarky21; 09.01.2012