我有两个模型,即公司和用户。 公司有很多用户。 当我保存公司时,我需要自动保存用户。 有没有一种方法可以让JPA实现这样的目标?
以下是我的模特:
//公司模式
@Entity
public class Company {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotNull
@Size(min = 4, max = 100)
private String name;
@Size(max = 500)
private String description;
@OneToMany(mappedBy = "company",cascade = CascadeType.ALL)
private List<User> users = new ArrayList<>();
public Company(){};
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
//用户模型
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(length = 50, unique = true)
@NotNull
@Size(min = 4, max = 50)
private String username;
@Column(length = 50)
@NotNull
@Size(min = 8, max = 50)
private String password;
@Column(length = 50)
@NotNull
@Size(min = 4, max = 50)
private String firstName;
@Column(length = 50)
@NotNull
@Size(min = 4, max = 50)
private String lastName;
@Column(length = 50, unique = true)
@NotNull
@Size(min = 4, max = 50)
private String email;
private Boolean enabled;
@Temporal(TemporalType.TIMESTAMP)
@NotNull
private Date lastPasswordReset;
@Column(nullable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
@CreatedDate
private Date createdAt;
@Column(nullable = false)
@Temporal(TemporalType.TIMESTAMP)
@LastModifiedDate
private Date updatedAt;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "user_authority",
joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "authority_id", referencedColumnName = "id")})
private List<Authority> authorities;
@ManyToOne(optional = false, fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
private Company company;
.... Followed by getters and setters
}
因此客户端发送一个请求有效负载,其中包含嵌套的JSON对象,如:
"company":{
"name":"Evil Corp",
"description":"test",
"users":[
{
"userName":"xyz",
"password":"abc" //folllowed by other attributes
}
]
}
//公司控制器
@RestController
@RequestMapping("/api/v1/company")
public class CompanyController {
@Autowired
ICompanyService companyService;
@RequestMapping(value = "/create", method = RequestMethod.POST)
public ResponseEntity<Company> create(@RequestBody Company company){
System.out.println("Request Recieved");
company = companyService.save(company);
return ResponseEntity.ok(company);
}
}
//服务
@Service
public class CompanyService implements ICompanyService {
@Autowired
CompanyRepository companyRepository;
@Override
public Company save(Company company) {
return companyRepository.save(company);
}
}
当我尝试保存时,我遇到以下异常:
Hibernate: insert into user (company_id, created_at, email, enabled, first_name, last_name, last_password_reset, password, updated_at, username, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2018-03-11 15:15:57.814 WARN 7733 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1048, SQLState: 23000
2018-03-11 15:15:57.816 ERROR 7733 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : Column 'company_id' cannot be null
2018-03-11 15:15:57.853 INFO 7733 --- [nio-8080-exec-2] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2018-03-11 15:15:57.881 ERROR 7733 --- [nio-8080-exec-2] o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
那么如何保存嵌套关联? 保存公司后,我是否需要手动设置user_id字段?我在使用 Rails 时已经完成了这样的事情。 Spring Boot上也存在这样的事情吗?
答案 0 :(得分:0)
公司ID是用户表中的外键,因此在将父对象和子对象保存在一起之前,请确保子对象应设置父对象。
例如,在您的情况下 - 在用户实体中有多对一的关系,如
@ManyToOne(optional = false, fetch = FetchType.LAZY, cascade =
CascadeType.REMOVE)
private Company company;
将此公司对象设置为用户对象,然后在将公司对象保存到数据库时自动插入其子对象。 您已使用 cascade = CascadeType.ALL ,因此它应插入子对象。