Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data was not saved: object references an unsaved transient instance - save the transient instance before flushing [duplicate]

Tags:

java

hibernate

I have a database with two tables User and Country. I want to relationship where many user can belong to one county. I implement this using hibernate using the following model classes:

@Entity (name = "user")
public class User {

   @Id @GeneratedValue (strategy = GenerationType.IDENTITY)
    private int userId;
    private String username;
    private String password;

   @ManyToOne ()
   @JoinColumn (name = "countryId")
   private Country country;

    //Getter & Setter
 }


@Entity (name = "country")
public class Country {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int countryId;
    private String countryName;
   //Getter & Setter
}

When I try to save the user object I get the following exception:

  org.hibernate.HibernateException: Data was not saved: object references an unsaved transient instance - save the transient instance before flushing: com.kyrogaming.models.Country

How can I fix the problem?

like image 673
Mario Dennis Avatar asked Jun 24 '13 19:06

Mario Dennis


2 Answers

You can't save things to Hibernate until you've also told Hibernate about all the other objects referenced by this newly saved object. So in this case, you're telling Hibernate about a User, but haven't told it about the Country.

You can solve problems like this in two ways.

Manually

Call session.save(country) before you save the User.

CascadeType

You can specify to Hibernate that this relationship should propagate some operations using CascadeType. In this case CascadeType.PERSIST would do the job, as would CascadeType.ALL.

Referencing existing countries

Based on your response to @zerocool though, you have a second problem, which is that when you have two User objects with the same Country, you are not making sure it's the same Country. To do this, you have to get the appropriate Country from the database, set it on the new user, and then save the User. Then, both of your User objects will refer to the same Country, not just two Country instances that happen to have the same name. Review the Criteria API as one way of fetching existing instances.

like image 139
sharakan Avatar answered Sep 17 '22 18:09

sharakan


Looks like Users that are added in your Country object, are not already present in the DB. You need to use cascade to make sure that when Country is persisted, all User which are not there in data but are associated with Country also get persisted.

Below code should help:

@ManyToOne (cascade = CascadeType.ALL)
   @JoinColumn (name = "countryId")
   private Country country;
like image 26
zerocool Avatar answered Sep 17 '22 18:09

zerocool