0

I have below JPA Tables. I have used uni-directional OneToMany relationship.

@Entity
@Table(name = "xxx")
public class Parent {
   @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
   @JoinColumn(name = "Child_ID")
   private Set<Child1> child;

   //getter setters

}

@Entity
@Table(name = "xxx")
public class Child {
   //other colmns

   //getter setters

}

When I first add entries to above parent Set(say 20) and save(), it saves to database successfully. Then In same set I have added 10 more and called save method. It save 10 new to db. If I again call save it add same 10 more to database again creating duplicate entries.

Parentrepository.save(parentObject);
Rohan Lopes
  • 165
  • 7
  • 18
  • 1
    can you show how you called the setting and saving of values? – arjayosma Nov 14 '18 at 06:47
  • @arjayosma : edited question. I am saving Parent object using repository. As it has cascadeType All it saves child as well. – Rohan Lopes Nov 14 '18 at 06:50
  • how did you populate your parentObject variable here. You must've saved the same object a lot of times without an updated ID. – arjayosma Nov 14 '18 at 06:59
  • @arjayosma : I am just saving same object multiple times. For some of the child's it update existing rows, but for OneToMany(set) object it insert again and again. – Rohan Lopes Nov 14 '18 at 07:37
  • Do you use the object that is returned by the save for further setting? – Tom Nov 14 '18 at 09:41
  • @Tom Yes..Its same object. As updates are happening on several steps in application. – Rohan Lopes Nov 14 '18 at 09:50
  • Maybe the answer of [this question](https://stackoverflow.com/questions/9732453/jpa-returning-an-auto-generated-id-after-persist) can help you – Tom Nov 14 '18 at 09:52
  • @Tom : Issue is like I have 3 steps in app where I update object. One object update successfully in db. In second step I add 10 more objects to Set<> which gets added to db. In 3rd step when I again same object those 2nd step objects are again saved(which gets duplicated). – Rohan Lopes Nov 14 '18 at 09:59

3 Answers3

1

Just generate valid Primary key in the Child entity, i.e

@Id
@Column(name = "child_name")
private String name;

and override @Equals and @HashCode methods:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Child )) return false;
    return name != null && name.equals(((Child) o).name);
}
@Override
public int hashCode() {
    return Objects.hashCode(this);
}
Nick
  • 744
  • 6
  • 11
  • I do have primary key in child table. It saves row to database but when I debugged object primary key is coming null. – Rohan Lopes Nov 14 '18 at 07:35
  • @RohanLopes that is because once you persist data in your DB, the key is being automagically created, but in your own local execution, the object holding your data, won't get the ID that has been saved from the database. – arjayosma Nov 14 '18 at 07:44
  • It updates for other 20 objects after save. Its sequence so the value update in primary key of child. But for those newly added childs in Set<> it doesn't. – Rohan Lopes Nov 14 '18 at 08:01
  • @RohanLopes How did you write you Child's Primary key? – Nick Nov 14 '18 at 08:07
  • I have created child object and associated with parent. Primary key for child will be automatically created by jpa. – Rohan Lopes Nov 14 '18 at 08:09
1

As per the code Parent class has one to many mappping with class Child.
Every time you are calling
Parentrepository.save(parentObject);
make sure that you have set the below line properly

parentObject.setChild(SetOfChildObjects);

Also override Equals and hashCode in Child class

if you set that improperly then then the tables in DB will get updated accordingly.

NOTE: for better analysis can you share the actual code?

TheSprinter
  • 1,523
  • 17
  • 30
0

I found the issue. Jpa repository saves the object and returns updated object.

    <S extends T> S save(S var1);

Entity object should be Immutable(Which I thought so). That means it updates values(in this case sequence number) after save operation. But after save operation it has not updated sequence number in same object. When I used returned object it worked. Below is changed code.

    parentObject = Parentrepository.save(parentObject);
Rohan Lopes
  • 165
  • 7
  • 18