Java 非空属性引用一个瞬态值 - 在当前操作之前必须保存瞬态实例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19074278/
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
Not-null property references a transient value - transient instance must be saved before current operation
提问by Tapas Jena
I have 2 domain models and one Spring REST Controller like below:
我有 2 个域模型和一个 Spring REST 控制器,如下所示:
@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:
弹簧休息控制器:
@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
}
I am trying to call above REST service with below JSON as body:
我正在尝试使用以下 JSON 作为正文调用上面的 REST 服务:
{
"firstname": "Tapas",
"lastname": "Jena",
"city": "Hyderabad",
"country": "1"
}
Where country code 1 is already there in Country table. The problem is when I am calling this service getting below error:
Country 表中已经存在国家代码 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
Any help will be appreciated!
任何帮助将不胜感激!
采纳答案by Raju Rudru
Try putting CascadeType.ALL
尝试放置 CascadeType.ALL
@OneToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;
回答by djejaquino
I had a similar problem. Two entities: Documentand Status.
Documenthad a relationship OneToMany
with Status, that represented the history of Statusthe Documenthad.
我有一个类似的问题。两个实体:Document和Status。
DocumentOneToMany
与Status有关系,它代表了Document拥有的Status的历史记录。
So, there was a @NotNull
@ManyToOne
reference of Documentinside Status.
因此,在Status 中有一个Document的@NotNull
@ManyToOne
引用。
Also, I needed to know the actual Statusof Document. So, I needed another relationship, this time @OneToOne
, also @NotNull
, inside Document.
另外,我需要知道实际情况的文件。所以,我需要另一个关系,这一次@OneToOne
,也在Document@NotNull
内部。
The problem was: how can I persist both entities the first time if both had a @NotNull
reference to the other?
问题是:如果两个实体都有对另一个的@NotNull
引用,我如何第一次持久化这两个实体?
The solution was: remove @NotNull
reference from actualStatus
reference. This way, it was able to persist both entities.
解决方案是:@NotNull
从actualStatus
参考中删除参考。这样,它就能够持久化两个实体。
回答by Miladesnovakaina
you should change :
你应该改变:
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;
to :
到 :
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="COUNTRY_ID")
private Country country;
just delete nullable setting.
只需删除可为空的设置。
回答by Nishchay Gupta
I got same error and this is how I solved it:
我遇到了同样的错误,这就是我解决它的方法:
1st Entity:
第一个实体:
@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;
2nd Entity:
第二实体:
@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;
My Controller:
我的控制器:
@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;
}
The problem got solved when I added "person.setCustomer(customer);". As both POJO classes has each others reference, so we have to "set" each others reference before using the JPA repository method(customerRepo.save(customer));
当我添加“person.setCustomer(customer);”时,问题就解决了。由于两个 POJO 类都有彼此的引用,所以我们必须在使用 JPA 存储库方法之前“设置”彼此的引用(customerRepo.save(customer));