2015-07-20 2 views
0

I эти устаревшие таблицы (в базе данных Oracle):Регистрация Наследование без дискриминатора колонки

CREATE TABLE "SPL_OWN"."SL_DOCUMENTO" ( 
    "ID_DOCUMENTO"  NUMBER(20,0) NOT NULL ENABLE, -- Primary Key 
    ... 
    "ID_PARECER_GERAL" NUMBER(20,0), -- Foreign Key 
    "ID_PROPOSITURA" NUMBER(20,0), -- Foreign Key 
    ... 
); 

CREATE TABLE "SPL_OWN"."SL_PARECER_GERAL" ( 
    "SL_PARECER_GERAL" NUMBER(20,0) NOT NULL ENABLE, -- Primary Key 
    ... 
); 

CREATE TABLE "SPL_OWN"."SL_PROPOSITURA" ( 
    "ID_PROPOSITURA" NUMBER(20,0) NOT NULL ENABLE, -- Primary Key 
    ... 
); 

Особенностью здесь является то, что значения SL_PARECER_GERAL.SL_PARECER_GERAL и SL_PROPOSITURA.ID_PROPOSITURA в том, равен SL_DOCUMENTO.ID_DOCUMENTO. На самом деле SL_PARECER_GERAL и SL_PROPOSITURA можно рассматривать как подклассы SL_DOCUMENTO (в этой ситуации есть другие таблицы, я использую эти два примера). В идеальной ситуации я должен использовать inheritance типа JOINED. Однако нет discriminator column.

детерминированным, если SL_DOCUMENTO является SL_PROPOSITURA, SL_DOCUMENTO.ID_PROPOSITURA должны быть заполнены, в то время как SL_DOCUMENTO.ID_PARECER_GERAL должны быть NULL. С другой стороны, если SL_DOCUMENTO.ID_PARECER_GERAL заполнен, а SL_DOCUMENTO.ID_PROPOSITURA - NULL, SL_DOCUMENTO - SL_PARECER_GERAL.

В моем сопоставлении я не использую стратегию наследования.

@Entity 
@Table(name = "SL_DOCUMENTO") 
public class DocumentoORM { 

    @Id 
    @Column(name = "ID_DOCUMENTO") 
    @SequenceGenerator(name = "SEQ_SL_DOCUMENTO", sequenceName = "SEQ_SL_DOCUMENTO") 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_SL_DOCUMENTO") 
    private Long id; 

    @OneToOne(mappedBy = "documento", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) 
    @JoinColumn(name = "ID_PARECER_GERAL", updatable = false) 
    private ParecerGeralORM parecerGeral; 

    @OneToOne(mappedBy = "documento", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) 
    @JoinColumn(name = "ID_PROPOSITURA", updatable = false) 
    private ProposituraORM propositura; 

} 

@MappedSuperclass 
public abstract class BaseORM extends AbstractORM { 

    @Id 
    private Long id; 

} 

@Entity 
@Table(name = "SL_PROPOSITURA") 
@AttributeOverrides({ @AttributeOverride(name = "id", column = @Column(name = "ID_PROPOSITURA")) }) 
public class ProposituraORM extends BaseORM { 

    @MapsId 
    @OneToOne(optional = false) 
    @JoinColumn(name = "ID_PROPOSITURA", nullable = false) 
    private DocumentoORM documento; 

    public ProposituraORM() { 
    } 

    public ProposituraORM(DocumentoORM documento) { 
     super(); 
     this.documento = documento; 
     this.documento.setPropositura(this); 
    } 

    // Getter & Setters 

} 

@Entity 
@Table(name = "SL_PROCESSO") 
@AttributeOverrides({ @AttributeOverride(name = "id", column = @Column(name = "ID_PROCESSO")) }) 
public class ProcessoORM extends BaseORM { 

    @MapsId 
    @OneToOne 
    @JoinColumn(name = "ID_PROCESSO") 
    private DocumentoORM documento; 

    public ProcessoORM() { 
    } 

    public ProcessoORM(DocumentoORM documento) { 
     this.setDocumento(documento); 
     documento.setProcesso(this); 
    } 

    // Getter & Setters 

} 

Когда ProposituraORM вставлен, JPA делает, что DocumentoORM быть сохранены до того экземпляра ProposituraORM. Однако, хотя SL_PROPOSITURA.ID_PROPOSITURA имеет то же значение, что и SL_DOCUMENTO.ID_DOCUMENTO, столбец SL_DOCUMENTO.ID_PROPOSITURA остается NULL. Чтобы исправить это, я должен создать обходной путь, где я его заполняю «вручную», в сторону собственного SQL. Очевидно, что тот же маханизм работает для ProcessoORM.

Поэтому я хотел бы знать, есть ли лучшая альтернатива использованию Присоединение наследования без столбца дискриминатора. В некоторых местах я нашел ссылки на аннотации @SecondaryTable и @PrimaryKeyJoinColumn. Здесь, в StackOverflow, я видел некоторые связанные вопросы, но я не смог применить их к своей ситуации.

Спасибо,

Рафаэль Афонсу

+0

Почему вы не смогли использовать '@ SecondaryTable'? Это похоже на хорошую ситуацию для вашей ситуации. Таким образом, вы будете иметь как классы «ProposituraORM», так и «ProcessoORM» с «@ SecondaryTable». Затем вы можете сделать «DocumentoORM» встраиваемым и вставить его в оба класса. – DuncanKinnear

+0

@ DuncanKinnear: Вы знаете какой-либо конкретный пример? Может не использовать аннотацию Inheritance. –

ответ

0

На самом деле, вы почти там.

Тип наследования TABLE_PER_CLASS, вероятно, сделает это. Другими словами, ваш BaseORM класс должен иметь

@Entity 
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) 
public class BaseORM extends AbstractORM { 

Вы даже не нужно будет использовать @SecondaryTable как DocumentoORM уже связан с @OneToOne.

Чтобы убедиться, что все идентификаторы заполнены правильно, вам необходимо определить ссылки на и сторон ассоциации. То есть, другими словами, если у вас есть два объекта documento и propositura затем, прежде чем сохранить вам нужно сделать следующее:

documento.setPropositura(propositura); 
propositura.setDocumento(documento);