0

Am new to JPA, I have one parent and child table, when ever there insert, update I need to log that activity in child table. So when there is insert or update on parent I need to insert record in child.

For example if there is update in parent then

 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(?,?)

so in JPA I tried to do update like this

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();

if I comment from Prepare child start to end I am able to update parent record, but along with update I need to insert record in child table with parent reference how to do this.

below are parent child TOs.

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

Thank You. Or please suggest if there is any other way.

user1912935
  • 361
  • 4
  • 13
  • 34
  • With "cascade = CascadeType.ALL" you only need update Java Objects with the new values and call the entity manager's methods persist or merge with parent entity as param – JLazar0 Jul 19 '19 at 05:58

1 Answers1

0

Try the following steps:

1.- Insert record.

2.- Get list of records to update

3.- Update with entityManager.merge () by setting the new values ​​on the entity.

Recently I had problems with CriteriaUpdate, since it is not synchronized with the context of persistence.

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

JLazar0
  • 1,257
  • 1
  • 11
  • 22