JPA更新父级插入子级

时间:2018-10-18 21:53:05

标签: jpa spring-data-jpa jpa-2.0 jpa-2.1

对于JPA来说,我是一个父级和子级表,当有插入,更新时,我需要将该活动记录在子级表中。 因此,当父项上有插入或更新时,我需要在子项中插入记录。

例如,如果父项中有更新,则

 insert into child (c1, c2, CHNGE_DT, c3, c4, P1, c5, c6, PK) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
 update parent set p1=?, p2=?, p3=?, p4=?, p5=?, p6=?, p7=?, LAST_UPD_DT = ? where p1=? and LAST_UPD_DT = ? and p3 not in(?,?)

所以在JPA中,我试图像这样进行更新

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaUpdate<parent> crit = criteriaBuilder.createCriteriaUpdate(parent.class);
    Root<parent> candidate = crit.from(parent.class);
    Timestamp currentTimeStamp = DateUtil.getESTSystemTimeStamp();
    crit.set(candidate.get("p1"), xxxxxxx);
    crit.set(candidate.get("p2"), xxxxxxx);
    crit.set(candidate.get("p3"), xxxxxxx);
    crit.set(candidate.get("p4"), xxxxxxx);
    crit.set(candidate.get("p5"), xxxxxxx);
    crit.set(candidate.get("p6"), xxxxxxx);
    crit.set(candidate.get("p7"), xxxxxxx);
    crit.set(candidate.get("lastUpdateDate"), currentTimeStamp);

    // Prepare child start
    List<child> childList = new child<>();
    child c = new child();
    c.setc1(xxxxxx);
    c.setc2(xxxxxx);
    c.setc3(xxxxxx);
    c.setc4(xxxxxx);
    c.setc5(xxxxxx);
    c.setc5(xxxxxx);
    c.setChangeDate(currentTimeStamp);
    c.setP1();//Dont understand what to put here
    childList.add(c);
    crit.set(candidate.get("child"), childList);
    // Prepare child end

    Predicate restrictions = criteriaBuilder.equal(candidate.get("lastUpdateDate"),
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(xxxxxxxxxxxx));
    restrictions = criteriaBuilder.and(restrictions,
            criteriaBuilder.equal(candidate.get("p1"), xxxxxxx));
    restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.not(candidate.get("p3")
            .in(xxxxx, xxxxx)));
    crit.where(restrictions);
    Query q = entityManager.createQuery(crit);
    int num = q.executeUpdate();

如果我从“准备子项”到“开始到末尾”之间的注释,我能够更新父记录,但是随着更新,我需要在子表中插入记录,并附上父级引用。

下面是亲子TO。

ParentTO:
@Entity
@Table(name = "Parent", schema = "XXXXX")
@Getter
@Setter
public class Parent implements Serializable {
    private static final long       serialVersionUID    = 5288911453481140793L;
    @Column(name = "P1")
    @Id
    @SequenceGenerator(name = "XXX", sequenceName = "XXXX", schema = "XXXX", allocationSize = 1)
    @GeneratedValue(generator = "XXXX")
    private Long                    p1;
    @Column(name = "P2")
    private Long                    p2;
    @Column(name = "P3")
    private Long                    p3; 
    @Column(name = "P4")
    private Long                    p4; 
    @Column(name = "P5")
    private Long                    p5; 
    @Column(name = "P6")
    private Long                    p6; 
    @Column(name = "P7")
    private Long                    p7;
    @OneToMany(mappedBy = "p1", cascade = CascadeType.ALL)
    @JsonManagedReference
    private List<Child> child;
}

ChildTO:

@Entity
@Table(name = "CHILD", schema = "XXXXX")
@Getter
@Setter
public class Child implements Serializable {
    private static final long   serialVersionUID    = 2168920063633405141L;
    @Column(name = "C1")
    @Id
    @SequenceGenerator(name = "XXXX", sequenceName = "XXXX", schema = "XXX", allocationSize = 1)
    @GeneratedValue(generator = "XXXXX")
    private Long                c1;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "P1")
    @JsonBackReference
    private Parent  p1;
    @Column(name = "C2")
    private String              c2;
    @Column(name = "C3")
    private String              c3;
    @Column(name = "C4")
    private String              c4;
    @Column(name = "C5")
    private String              c5;
}

谢谢。 或请建议是否还有其他方法。

1 个答案:

答案 0 :(得分:0)

尝试以下步骤:

1.-插入记录。

2.-获取要更新的记录列表

3.-通过在实体上设置新值来更新entityManager.merge()。

最近,由于CriteriaUpdate与持久性上下文不同步,因此我遇到了问题。

Insert and Update with CriteriaBuilder JPA in the same transactional method throws error "ForeignKey not exists"