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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 13:53:44  来源:igfitidea点击:

Not-null property references a transient value - transient instance must be saved before current operation

javajsonspringhibernaterest

提问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 OneToManywith Status, that represented the history of Statusthe Documenthad.

我有一个类似的问题。两个实体:DocumentStatusDocumentOneToManyStatus有关系,它代表了Document拥有的Status的历史记录

So, there was a @NotNull@ManyToOnereference 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 @NotNullreference to the other?

问题是:如果两个实体都有对另一个的@NotNull引用,我如何第一次持久化这两个实体?

The solution was: remove @NotNullreference from actualStatusreference. This way, it was able to persist both entities.

解决方案是:@NotNullactualStatus参考中删除参考。这样,它就能够持久化两个实体。

回答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));