简体   繁体   中英

spring-boot-starter-data-jpa @OneToMany does not insert new child when it's an update

Parent:

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class A {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Long id;

@OneToMany(cascade = {CascadeType.ALL}, orphanRemoval = true)
public List<Child> child = new LinkedList<>();

}

Child:

@Entity
public class Child {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Long child_id;

}

Repository:

import org.springframework.data.repository.CrudRepository;
@Transactional
public interface ARepository extends CrudRepository<A,Long> {

@Query("SELECT x FROM A x WHERE x.syncTimestamp IS NULL")
List<A> findAs();
}

Persisting : Update

public class SomeClass {

  @Autowired
  private ARepository repo;

  public void someMethod() {

    List<A> as = repo.findAs();
    A firstA = as.get(0);
    firstA.child.add(new Child());
    repo.save(firstA);
  }    

}

When I insert a new A object, everything works fine, all the child insert well in the database.

But when I load an A object from the database, add some child to the list and then update the object, this doesn't insert the new child.

According to the documentation for CascadeType, ALL should insert them.

Any idea how to fix this?

That's because you don't have a reference to the A class inside the Child class :

@Entity
public class A {
...
     @OneToMany(mappedBy = "a", cascade = {CascadeType.ALL}, orphanRemoval = true)
     public List<Child> child = new LinkedList<>();
}

@Entity
public class Child {
...
    @ManyToOne
    @JoinColumn(name = "your_table_name")
    private A a;
...
}

This one is working for me. Please try again in following way your child entity will get updated:

public class SomeClass {

    @Autowired
    private ARepository repo;

    public void someMethod() {

        List<A> as = repo.findAs();
        A firstA = as.get(0);
        List<Child> childs=firstA.getChild();

        // add new child value
        childs.add(new Child("Test"));
        firstA.setChild(childs);

        for (Child child : childs) {
            child.setA(firstA);
        }
        repo.save(firstA);
    }    

}


import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;

@Entity
public class Child {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Long child_id;

    public Child(String name) {
        // TODO Auto-generated constructor stub
        this.name=name;
    }

    public Child() {
        // TODO Auto-generated constructor stub
    }
    private String name;

    @ManyToOne
    @JoinColumn(name="a_id")
    private A a;

    //your getter setter

}

import java.util.LinkedList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class A {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Long id;

    private String syncTimestamp=null;

    @OneToMany(mappedBy="a", cascade=CascadeType.ALL)
    public List<Child> child = new LinkedList<>();

    // your getter setter

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM