【问题标题】:JPA: How to fill related entity after the master is insertedJPA:插入master后如何填写相关实体
【发布时间】:2015-07-14 07:12:18
【问题描述】:

我有两个表,分别名为 SL_DOCUMENTSL_PROPOSESL_DOCUMENT 有自己的 ID (ID_DOCUMENT) 和 SL_PROPOSE (ID_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);

当我真正插入文档时,根据上面的 sn-ps,我在控制台(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 填充此列。你有更好的想法吗?

谢谢,

拉斐尔·阿方索

【问题讨论】:

    标签: jpa orm mapping


    【解决方案1】:

    我看到的解决方案是让 ProposeORM 的 ID 不自动生成,因为您总是希望它具有它链接到的文档的 ID,并且在文档表中仍然有一个连接列:

    @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);
        }
    }
    

    您必须先持久化文档,刷新 EntityManager 以确保文档具有生成的 ID,然后持久化提议并将其设置到文档中。

    【讨论】:

    • 我这样做了:在调用 insert DAO 方法后,我按照您的建议刷新了实体管理器。接下来,我调用了一个方法,该方法通过 Native SQL 更新了SL_DOCUMENT.ID_PROPOSE,并再次刷新了实体管理器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-09
    • 2011-06-29
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多