JPA:如何在插入主数据后填充相关实体

时间:2015-05-04 19:01:53

标签: jpa orm mapping

我有两个名为SL_DOCUMENTSL_PROPOSE的表。 SL_DOCUMENT有自己的ID(ID_DOCUMENT)和SL_PROPOSEID_PROPOSE)的外键。 SL_PROPOSE ID列为ID_PROPOSE。特殊性是SL_PROPOSE ID值实际上是SL_DOCUMENT.ID_DOCUMENT值。即,在插入新的SL_DOCUMENT后,应插入相关的SL_PROPOSE,其中SL_DOCUMENT.ID_DOCUMENT为ID,稍后应在SL_DOCUMENT.ID_PROPOSE列中使用相同的值。

我按照以下方式完成了JPA映射:

@Entity
@Table(name = "SL_DOCUMENT")
public class DocumentORM {

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

    @OneToOne(mappedBy = "document", cascade = { CascadeType.PERSIST })
//  @JoinColumn(name = "ID_PROPOSE", updatable = false)
    private ProposeORM propose;

    // ...

}


@Entity
@Table(name = "SL_PROPOSE")
public class ProposeORM  {

    @Id
    @Column(name = "ID_PROPOSE")
    private Long id;

    @MapsId
    @OneToOne
    @JoinColumn(name="ID_PROPOSE")
    private DocumentORM document;

    // ...

    public ProposeORM(DocumentORM document) {
        super();
        this.document = document;
        this.document.setPropositura(this);
    }

}

创建DocumentORM和ProposeORM的新实例:

DocumentORM document = new DocumentORM();
ProposeORM propose = new ProposeORM(document);

最后用ProposeORM插入新文档:

this.documentoDAO.insert(document);

当我真正插入文档时,根据上面的代码片段,我在控制台(Websphere 8.5)中看到SL_DOCUMENTSL_PROPOSE正确运行的INSERT命令。但是,当我看到表格时,SL_DOCUMENT.ID_PROPOSE列仍然是NULL。即使我取消注释DocumentORM.propose上的@JoinColumn注释,SL_DOCUMENT.ID_PROPOSE列仍未填充。

理想情况是SL_DOCUMENT有一个鉴别器列,而ProposeORM是一个DocumentORM子类,使用JOINED InheritanceType(还有其他表与SL_DOCUMENT具有相同的关系) 。但是,这些是遗留表,无法更改它。

那么,填充SL_DOCUMENT.ID_PROPOSE的替代方法是什么?我正在考虑的解决方法是使用本机SQL填充此列。你有更好的想法吗?

谢谢,

Rafael Afonso

1 个答案:

答案 0 :(得分:1)

The solution I see is to make ProposeORM's ID not auto-generated, since you always want it to have the ID of the document it's linked to, AND still have a join column in the document table:

@Entity
@Table(name = "SL_DOCUMENT")
public class DocumentORM {

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

    @OneToOne
    @JoinColumn(name = "ID_PROPOSE")
    private ProposeORM propose;

    // ...
}


@Entity
@Table(name = "SL_PROPOSE")
public class ProposeORM  {

    @Id
    @Column(name = "ID_PROPOSE")
    private Long id;

    @OneToOne(mappedBy = propose)
    private DocumentORM document;

    // ...

    public ProposeORM(DocumentORM document) {
        super();
        this.id = document.getId();
        this.document = document;
        this.document.setPropositura(this);
    }
}

You'll have to persist the document first, flush the EntityManager to make sure the document has a generated ID, and then persist the propose and set it into the document.