0

I have Entity classes like following:

@Entity
@Table(name = "PARENT")
public class Parent {
   @OneToMany(mappedBy = "parent")
   private List<Child> childs;
}

and

@Entity
@Table(name = "CHILD")
public class Child {
    @ManyToOne
    @JoinColumn(name = "PARENT_ID", referencedColumnName = "ID", insertable = false, updatable = false)
    private Parent parent;
}

In my code, when I am trying to save a Child the Parent is also getting saved:

Parent parent = parentRepository.findOne(id);
//Code which changes parent attributes
child.setParent(parent);
childRepository.save(child);

I have not used parentRepository.save(), any cascade. And insertable, updatable is also set to false. Is it happening because parent object is attached to context for parentRepository.findOne(id); call? How to avoid this?

PS: I am using spring-boot 1.5.9, Spring Data

Deb
  • 5,163
  • 7
  • 30
  • 45
  • 1
    It's happening because that's the basic principle of managed JPA entities. They are managed. So any change you make is automatically being saved in the database. If you don't want to change the parent, then don't change it. Putting ìnsertable=false and updatable=false is nonsensical: you want to be able to set or modify the parent of a child. – JB Nizet Nov 25 '18 at 08:34
  • There's a good explanation to this here: https://stackoverflow.com/questions/43002110/how-to-prevent-saving-child-object-with-jpa – Aditya Narayan Dixit Nov 25 '18 at 08:34
  • @JBNizet, I have to change parent for business logic. I tried to clone the child object like this: `Parent parentClone = new Parent(); BeanUtils.copyProperties(parent, parentClone); child.set(parentClone)`. Here `parentClone` is not managed. But still the same result. – Deb Nov 25 '18 at 08:41
  • *I have to change parent for business logic*: But apparently the requirements here is that the parent should not be modified. So, if your business logic modifies the parent, it's simply wrong. – JB Nizet Nov 25 '18 at 08:46
  • Actually there is an Embeddable object common to parent and child. Which is changing. and I am using parent as a dto. Based on condition it will be either saved to parentRepo or childRepo. However, this can be changed, if JPA does not allow changing managed entities. I am wondering how the changes are getting committed without calling `save()` method. – Deb Nov 25 '18 at 08:59
  • Or, is there any way of detaching the entity in spring-data – Deb Nov 25 '18 at 09:00
  • *there is an Embeddable object common to parent and child*: so that's a first bug. An embeddable object shouldn't be shared by two entities. *I am using parent as a dto*: that's a second problem: an entity is not a DTO, and a DTO is not an entity. *if JPA does not allow changing managed entities*: it does allow changing managed entities. Why do you think it doesn't? – JB Nizet Nov 25 '18 at 09:05
  • *how the changes are getting committed without calling save() method*: because they are managed: either the entity manager loaded them, or you persisted/merged them. So the entity manager knows all the entities being used, tracks their changes, and saves them automatically. – JB Nizet Nov 25 '18 at 09:05

0 Answers0