java Spring Data 一对多映射
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31172021/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Data one to many mapping
提问by Iurii
I try to configure OneToManyand ManyToOnemapping in Spring Data project but have some issues.
我尝试在 Spring Data 项目中配置OneToMany和ManyToOne映射,但有一些问题。
So I have two entities: Employerand Project. One Employer could have many projects.
所以我有两个实体:Employer和Project。一个雇主可以有多个项目。
Entity classes:
实体类:
Employer.java
雇主.java
@Entity
@Table (name="Employer")
public class Employer {
@Id
@SequenceGenerator(name="my_seq", sequenceName="GLOBAL_SEQUENCE")
@GeneratedValue(strategy = GenerationType.SEQUENCE ,generator="my_seq")
@Column (name="employer_id")
private int id;
@Column (name="name")
private String name;
@JoinColumn (name="employer_id")
@OneToMany(mappedBy = "employer", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Project> project = new HashSet<Project>();
......................
}
Project.java
项目.java
@Entity
@Table (name="Project")
public class Project {
@Id
@SequenceGenerator(name="my_seq", sequenceName="GLOBAL_SEQUENCE")
@GeneratedValue(strategy = GenerationType.SEQUENCE ,generator="my_seq")
@Column (name="project_id")
private int id;
@Column (name="name")
private String name;
@ManyToOne
@JoinColumn(name="employer_id", nullable = false)
private Employer employer;
......................
}
Repository classes:
存储库类:
public interface EmployerRepository extends JpaRepository<Employer, Integer> {
}
public interface ProjectRepository extends JpaRepository<Project, Integer> {
}
Services:
服务:
@Service
public class EmployerServiceImpl implements EmployerService {
@Autowired
private EmployerRepository employerRepository;
@Override
public List<Employer> getAllEmployers() {
return employerRepository.findAll();
}
}
@Service
public class ProjectServiceImpl implements ProjectService {
@Autowired
private ProjectRepository projectRepository;
@Override
public List<Project> getAllProjects() {
return projectRepository.findAll();
}
}
Controller:
控制器:
@Controller
public class MainController {
private EmployerService employerService;
private ProjectService projectService;
@Autowired(required = true)
@Qualifier(value = "employerService")
public void setEmployerService(EmployerService employerService) {
this.employerService = employerService;
}
@Autowired(required = true)
@Qualifier(value = "projectService")
public void setProjectService(ProjectService projectService) {
this.projectService = projectService;
}
@RequestMapping(value="/employers", method=RequestMethod.GET)
public @ResponseBody List<Employer> getEmployers(@RequestParam(value = "name", required = false) String name) {
return employerService.getAllEmployers();
}
..............................
}
Employer table:
雇主表:
EMPLOYER_ID . NAME
......................
1 . Google
2 . Oracle
3 . Facebook
Project table:
项目表:
PROJECT_ID . NAME . EMPLOYER_ID
.......................................
1 . Create web site . 1
2 . Create reporting . 2
3 . Create web service . 3
4 . Fixing web site . 1
I'm expecting something like this:
我期待这样的事情:
[{"id":1,"name":"Google","project":[{"id":1,"name":"Create web site"}, {"id":4,"name":"Fixing web site"}},
{"id":2,"name":"Oracle","project":{"id":2,"name":"Create reporting"}},
{"id":3,"name":"Facebook","project":{"id":3,"name":"Create web service"}}]
But getEmployers
method from controller
class return this one:
但是getEmployers
来自controller
类的方法返回这个:
[{"id":1,"name":"Oracle","project":[{"id":4,"name":"Fixing web site",
"employer":{"id":1,"name":"Oracle","project":[{"id":4,"name":"Fixing web site",
"employer":{"id":1,"name":"Oracle","project":[{"id":4,"name":"Fixing web site",
"employer":{"id":1,"name":"Oracle","project":[{"id":4,"name":"Fixing web site",
"employer":{"id":1,"name":"Oracle","project":[{"id":4,"name":"Fixing web site",
"employer":{"id":1,"name":"Oracle","project":[{"id":4,"name":"Fixing web site","employer":
...................
Please sorry if this question discussed many times but I didn't find any suitable answer.
如果这个问题讨论了很多次,但我没有找到任何合适的答案,请见谅。
Thanks in advance!
提前致谢!
采纳答案by manish
You have a bi-directional association between Employer
s and Project
s. Additionally, you have configured both sides of the association to be loaded EAGER
ly (@ManyToOne
associations are fetched EAGER
ly by default and you have forced the @OneToMany
side to be fetched EAGER
ly as well). Due to this configuration, when the serialization framework loads the Employer
s, it finds valid Project
s that have back-links to the Employer
s and ends up getting stuck in a cyclic loop.
您在Employer
s 和Project
s之间存在双向关联。此外,您已将关联的两端配置为EAGER
ly加载(默认情况下@ManyToOne
会获取关联EAGER
,并且您也已强制@OneToMany
获取该端EAGER
)。由于这种配置,当序列化框架加载Employer
s 时,它会找到Project
具有指向Employer
s 的反向链接的有效s,并最终陷入循环循环中。
In order to get the result you want, you will have to mark the @ManyToOne
side (on the Project
entity) to be fetched LAZY
ly as @ManyTone(fetch = FetchType.LAZY)
.
为了获得您想要的结果,您必须将要提取的@ManyToOne
一侧(在Project
实体上)标记LAZY
为@ManyTone(fetch = FetchType.LAZY)
。
回答by Diwa Har
Add the @JsonManagedReference In the forward part of the relationship (i.e. User.java class):
在关系的前向部分添加@JsonManagedReference(即User.java类):
@Entity
public class User implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
@Column(name="name")
private String name;
@ManyToMany
@JoinTable(name="users_roles",joinColumns=@JoinColumn(name = "user_fk"), inverseJoinColumns=@JoinColumn(name = "role_fk"))
@JsonManagedReference
private Set<Role> roles = new HashSet<Role>();
...
Add the @JsonBackReference In the back part of the relationship (i.e. Role.java class):
在关系的后面部分添加@JsonBackReference(即Role.java类):
@Entity
public class Role implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@ManyToMany(mappedBy="roles")
@JsonBackReference
private Set<User> users = new HashSet<User>();
...
This works very well for me. :-)
这对我来说非常有效。:-)