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

87,706

Solution 1

Try putting CascadeType.ALL

@OneToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name="COUNTRY_ID", nullable=false) 

private Country country;

Solution 2

I had a similar problem. Two entities: Document and Status. Document had a relationship OneToMany with Status, that represented the history of Status the Document had.

So, there was a @NotNull @ManyToOne reference of Document inside Status.

Also, I needed to know the actual Status of Document. So, I needed another relationship, this time @OneToOne, also @NotNull, inside Document.

The problem was: how can I persist both entities the first time if both had a @NotNull reference to the other?

The solution was: remove @NotNull reference from actualStatus reference. This way, it was able to persist both entities.

Solution 3

I had the exact same problem. The solution seems to be to send the JSON like this:

{
  "firstname": "Tapas",
  "lastname": "Jena",
  "city": "Hyderabad",
  "country": {"id":"1"}
}

I guess @RequestBody tries to map an entity not a single field since the Customer instance is referencing a Country instance.

(I have similarly two entities, joined. In the DB, records for the referenced entity (Country in your case) were already created but the entity creation (Customer in your case) with a json, provided the same error message. For me CascadeType.ALL not helped but the above written change in the JSON solved the problem. For further config of course CascadeType can be considered.)

Share:
87,706
Tapas Jena
Author by

Tapas Jena

I am a Senior Java/J2ee engineer and Open Source developer from India. I am passionate about java and related open source stuffs.

Updated on January 11, 2021

Comments

  • Tapas Jena
    Tapas Jena over 3 years

    I have 2 domain models and one Spring REST Controller like below:

    @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:

    {
        "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:

    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!

  • Raju Rudru
    Raju Rudru over 10 years
    Ok then do one thing. Your customer object has country object with id 1. But that country object is not in persistence state. First get country object by sending country id. Set the country object retrieved from database into Customer object. Then save customer object. I hope this time it won't give any error.
  • skolima
    skolima over 9 years
    This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. You can also add a bounty to draw more attention to this question once you have enough reputation.
  • djejaquino
    djejaquino over 9 years
    I presented a solution to my problem which was similar. Nothing to do with a new question.
  • Asma Rahim Ali Jafri
    Asma Rahim Ali Jafri over 4 years
    can you please explain how the nullable tends to be problematic in this case?
  • eCommerce Guru
    eCommerce Guru over 4 years
    Bizarrely, CascadeType.ALL works for me when this doesn't: @ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })