我有两个域模型和一个Spring REST Controller,如下所示:
@Entity
public class Customer{
@Id
private Long id;
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;
// other stuff with getters/setters
}
@Entity
public class Country{
@Id
@Column(name="COUNTRY_ID")
private Integer id;
// other stuff with getters/setters
}
Spring REST控制器:
@Controller
@RequestMapping("/shop/services/customers")
public class CustomerRESTController {
/**
* Create new customer
*/
@RequestMapping( method=RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
@ResponseBody
public com.salesmanager.web.entity.customer.Customer createCustomer(@Valid @RequestBody Customer customer, Model model, HttpServletRequest request, HttpServletResponse response) throws Exception {
customerService.saveOrUpdate(customer);
return customer;
}
// other stuff
}
我正在尝试使用以下JSON作为正文来调用上面的REST服务:
{
"firstname": "Tapas",
"lastname": "Jena",
"city": "Hyderabad",
"country": "1"
}
国家/地区代码1已存在于国家/地区表格中。问题是当我调用此服务时出现以下错误:
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation: com.test.model.Customer.country -> com.test.model.Country; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation: com.test.model.Customer.country -> com.test.model.Country
任何帮助将不胜感激!
答案 0 :(得分:40)
尝试使用CascadeType.ALL
@OneToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;
答案 1 :(得分:12)
我有类似的问题。两个实体:文档和状态。
文档的关系OneToMany
与状态,表示文档的状态的历史记录。
因此,状态中有<{1>} @NotNull
文档的参考。
另外,我需要知道文档的实际状态。所以,我需要另一种关系,这次@ManyToOne
,还有@OneToOne
,在文档中。
问题是:如果两个实体都有@NotNull
引用另一个,我怎么能第一次坚持这两个实体呢?
解决方案是:从@NotNull
引用中删除@NotNull
引用。通过这种方式,它能够持久保存两个实体。
答案 2 :(得分:1)
你应该改变:
Header
到:
UIScrollView
只需删除可空设置。
答案 3 :(得分:1)
我遇到了完全相同的问题。解决方案似乎是像这样发送 JSON:
{
"firstname": "Tapas",
"lastname": "Jena",
"city": "Hyderabad",
"country": {"id":"1"}
}
我猜 @RequestBody
尝试映射实体而不是单个字段,因为 Customer 实例引用了 Country 实例。
(我有类似的两个实体,加入。在数据库中,已创建引用实体(在您的情况下为国家)的记录,但使用 json 的实体创建(在您的情况下为客户)提供了相同的错误消息。对我来说 CascadeType.ALL 没有帮助,但上面在 JSON 中的书面更改解决了问题。对于进一步的配置,当然可以考虑 CascadeType。)
答案 4 :(得分:0)
我遇到了同样的错误,这就是我的解决方法:
第一个实体:
@Entity
public class Person implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int personId;
private String name;
private String email;
private long phoneNumber;
private String password;
private String userType;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "personCustomer", cascade
= CascadeType.ALL)
private Customer customer;
第二个实体:
@Entity
public class Customer implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int customerId;
@OneToOne(fetch = FetchType.LAZY, optional = false, cascade =
CascadeType.ALL)
@JoinColumn(name = "person_customer")
@JsonIgnore
private Person personCustomer;
我的控制器:
@PostMapping("/customer/registration")
public PersonCustomer addCustomer(@RequestBody Person person)
{
Customer customer = new Customer(person);
person.setCustomer(customer);
Customer cust = customerRepo.save(customer);
logger.info("{}", cust);
Optional<Person> person_Cust =
personRepo.findById(cust.getPersonCustomer().getPersonId());
Person personNew = person_Cust.get();
PersonCustomer personCust = new PersonCustomer();
if(cust.equals(null))
{
personCust.setStatus("FAIL");
personCust.setMessage("Registration failed");
personCust.setTimestamp(personCust.timeStamp());
}
personCust.setStatus("OK");
personCust.setMessage("Registration OK");
personCust.setTimestamp(personCust.timeStamp());
personCust.setPerson(personNew);
return personCust;
}
当我添加“ person.setCustomer(customer);”时,问题得到解决。 由于两个POJO类都有彼此的引用,因此在使用JPA存储库方法(customerRepo.save(customer))之前,我们必须“设置”彼此的引用。