了解 Spring JPA 映射
Understanding Spring JPA mapping
我正在努力了解 Spring 数据 JPA 映射。我写了一个简单的应用程序,它有一个 Person
和 Child
对象。每个 Person
可以有很多 Child
关系,每个 Child
可以有一个 Person
import com.example.demo.children.Child;
import lombok.Data;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Data
public class Person {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
//Only used for Spring data JPA so use protected
protected Person() {}
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@OneToMany(
mappedBy = "person",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.EAGER
)
private List<Child> children = new ArrayList<>();
@Override
public String toString() {
return String.format(
"Person[id=%d, firstName='%s', lastName='%s', children='%s']",
id, firstName, lastName, children);
}
}
import com.example.demo.person.Person;
import lombok.Data;
import javax.persistence.*;
@Entity
@Data
public class Child {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
protected Child() {}
public Child(String first, String last) {
this.firstName = first;
this.lastName = last;
}
@ManyToOne(fetch = FetchType.EAGER)
private Person person;
@Override
public String toString() {
return String.format(
"Child[id=%d, firstName='%s', lastName='%s', parent='%s']",
id, firstName, lastName, person);
}
}
主要 class,
import java.util.ArrayList;
import java.util.List;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public CommandLineRunner demo(PersonRepository repository, ChildRepository cRepo) {
return (args) -> {
// save a few people
Person dad = new Person("John", "Jones");
Child c1 = new Child("Emily", "Jones");
Child c2 = new Child("Thomas", "Jones");
List<Child> kids = new ArrayList<>();
kids.add(c1);
kids.add(c2);
dad.setChildren(kids);
repository.save(dad);
Person p = repository.findById(1);
System.out.println(p);
};
}
}
当 运行 以上时,我得到 Person[id=1, firstName='John', lastName='Jones', children='[]']
和一个空的 Child
对象列表。如果我添加
List<Child> children = cRepo.findAll();
p.setChildren(children);
在打印出 Person
对象之前 System.out.println(p);
然后我得到 Person[id=1, firstName='John', lastName='Jones', children='[Child[id=2, firstName='Emily', lastName='Jones', parent='null'], Child[id=3, firstName='Thomas', lastName='Jones', parent='null']]']
因此 Child
没有与 Person
对象一起保存在数据库中。
我无法弄清楚我做错了什么才能让它正常工作。
虽然 save
成功地从 parent 级联到其关联的 children (CascadeType.ALL
),但 child objects 做没有在保存时设置他们的“爸爸”(person
)。
并且由于它们是关联的拥有方,它们的关系不会持久化,因此在下次检索时留下一个空的 children 列表parent 人。
要使您的代码正常工作,只需添加适当的双向关联同步,例如通过在 children.
上调用 c1.setPerson(dad)
https://vladmihalcea.com/jpa-hibernate-synchronize-bidirectional-entity-associations/
我正在努力了解 Spring 数据 JPA 映射。我写了一个简单的应用程序,它有一个 Person
和 Child
对象。每个 Person
可以有很多 Child
关系,每个 Child
可以有一个 Person
import com.example.demo.children.Child;
import lombok.Data;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Data
public class Person {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
//Only used for Spring data JPA so use protected
protected Person() {}
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@OneToMany(
mappedBy = "person",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.EAGER
)
private List<Child> children = new ArrayList<>();
@Override
public String toString() {
return String.format(
"Person[id=%d, firstName='%s', lastName='%s', children='%s']",
id, firstName, lastName, children);
}
}
import com.example.demo.person.Person;
import lombok.Data;
import javax.persistence.*;
@Entity
@Data
public class Child {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
protected Child() {}
public Child(String first, String last) {
this.firstName = first;
this.lastName = last;
}
@ManyToOne(fetch = FetchType.EAGER)
private Person person;
@Override
public String toString() {
return String.format(
"Child[id=%d, firstName='%s', lastName='%s', parent='%s']",
id, firstName, lastName, person);
}
}
主要 class,
import java.util.ArrayList;
import java.util.List;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public CommandLineRunner demo(PersonRepository repository, ChildRepository cRepo) {
return (args) -> {
// save a few people
Person dad = new Person("John", "Jones");
Child c1 = new Child("Emily", "Jones");
Child c2 = new Child("Thomas", "Jones");
List<Child> kids = new ArrayList<>();
kids.add(c1);
kids.add(c2);
dad.setChildren(kids);
repository.save(dad);
Person p = repository.findById(1);
System.out.println(p);
};
}
}
当 运行 以上时,我得到 Person[id=1, firstName='John', lastName='Jones', children='[]']
和一个空的 Child
对象列表。如果我添加
List<Child> children = cRepo.findAll();
p.setChildren(children);
在打印出 Person
对象之前 System.out.println(p);
然后我得到 Person[id=1, firstName='John', lastName='Jones', children='[Child[id=2, firstName='Emily', lastName='Jones', parent='null'], Child[id=3, firstName='Thomas', lastName='Jones', parent='null']]']
因此 Child
没有与 Person
对象一起保存在数据库中。
我无法弄清楚我做错了什么才能让它正常工作。
虽然 save
成功地从 parent 级联到其关联的 children (CascadeType.ALL
),但 child objects 做没有在保存时设置他们的“爸爸”(person
)。
并且由于它们是关联的拥有方,它们的关系不会持久化,因此在下次检索时留下一个空的 children 列表parent 人。
要使您的代码正常工作,只需添加适当的双向关联同步,例如通过在 children.
上调用c1.setPerson(dad)
https://vladmihalcea.com/jpa-hibernate-synchronize-bidirectional-entity-associations/