如何使用@ResponseBody创建jpa实体加入关系
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用@ResponseBody创建jpa实体加入关系相关的知识,希望对你有一定的参考价值。
我有两个实体成员,部门。会员必须在一个部门。
public class Member {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private String number;
@NonNull
@Column(nullable=false)
private String name;
@ManyToOne
@JoinColumn(name="department_number")
@NonNull
@JsonIdentityReference
private Department department;
}
public class Department {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int department_number;
@NonNull
@Column(nullable=false, unique=true)
private String name;
@OneToMany(mappedBy="department")
@JsonBackReference
private List<Member> members;
}
而我在控制器中的方法是这样的
@RequestMapping(method=RequestMethod.POST, path="/member/")
public ResponseEntity<Member>
createMember(@RequestBody Member member) {
return new ResponseEntity<Member>(
memberRepository.save(member)
, HttpStatus.OK);
}
当我试试这个
POST localhost:8080/member/
{
"name": "test",
"department": {
"name": "human resource"
}
}
我收到这个错误
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.dao.InvalidDataAccessApiUsageException",
"message": "org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : rura6502.tistory.com.domain.Member.department -> rura6502.tistory.com.domain.Department; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : rura6502.tistory.com.domain.Member.department -> rura6502.tistory.com.domain.Department",
"path": "/member/"
因为部门参数我知道这个错误。没有department_number(@Id),实体无法识别“人力资源”。我必须要求这个结构
{
"name": "test",
"department": {
"name": "human resource",
"department_number": 1
}
}
有没有办法用我的结构创建成员?(没有department_number结构.department.name也是唯一的)
答案
您必须在父集合中使用cascade=CascadeType.ALL
来指示hibernate也保存您的孩子。
@ManyToOne
@JoinColumn(cascade=CascadeType.ALL, name="department_number")
@NonNull
@JsonIdentityReference
private Department department;
如果您将使用双向关系,则还必须在子集合中指定级联类型。
您可能还需要修复Id
的Member
另一答案
成员对象之前需要部门对象。所以可以试试这个:
@RequestMapping(method= RequestMethod.POST, path="/member")
public ResponseEntity<Member> createMember(@RequestBody Member member) {
// Get department name from json
String deptName = member.getDepartment().getName();
Department department = null;
//check if dept already exists
Department alreadyExistsDepartment = departmentRepository.findByName(deptName);
if(alreadyExistsDepartment == null){
Department department1 = new Department();
department1.setName(deptName);
department = departmentRepository.save(department1);
} else{
department = alreadyExistsDepartment;
}
member.setDepartment(department);
memberRepository.save (member);
//other code here
}
这是为实体类建模的正确方法:
member.Java
@Entity
public class Member {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long memberId;
@NonNull
@Column(nullable=false)
private String name;
@ManyToOne
@JoinColumn(name="department_id")
private Department department;
// getters and setters
}
department.Java
@Entity
public class Department {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long departmentId;
@NonNull
@Column(nullable=false, unique=true)
private String name;
@OneToMany(mappedBy="department")
@JsonBackReference
private List<Member> members;
// getters and setters
}
department repository.Java
@Repository
public interface DepartmentRepository extends JpaRepository<Department, Long> {
Department findByName(String name);
}
以上是关于如何使用@ResponseBody创建jpa实体加入关系的主要内容,如果未能解决你的问题,请参考以下文章