I have a simple one-to-one relation:
PersonDao personDao = ctx.getBean(PersonDao.class, "personDaoImpl");
VehicleDao vehicleDao = ctx.getBean(VehicleDao.class, "vehicleDaoImpl");
Vehicle vehicle = new Vehicle("Audi");
Person person = new Person("Mike");
vehicle.setPerson(person);
person.setVehicle(vehicle);
personDao.save(person);
vehicleDao.save(vehicle);
Whenever I run the application I get the following exception:
Exception in thread "main" org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved mike.Person.vehicle -> mike.Vehicle; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : mike.Person.vehicle -> mike.Vehicle
I tried saving the entities in both orders:
personDao.save(person);
vehicleDao.save(vehicle);
and
vehicleDao.save(vehicle);
personDao.save(person);
and I get the same exception.
I was able to solve this by:
The question is if are there any better solutions? Maybe I'm doing something fundamentally wrong?
Here are the (trivial) entities and DAOs:
@Entity
public class Person {
@Id @GeneratedValue
private int id;
private String name;
@OneToOne
private Vehicle vehicle;
/* getters, setters, constructors */
}
--
@Entity
public class Vehicle {
@Id @GeneratedValue
private int id;
private String name;
@OneToOne
private Person person;
/* getters, setters, constructors */
}
--
@Repository
public class PersonDaoImpl implements PersonDao {
@PersistenceContext
private EntityManager em;
@Transactional
public void save(Person p) {
em.persist(p);
}
}
--
@Repository
public class VehicleDaoImpl implements VehicleDao {
@PersistenceContext
private EntityManager em;
@Transactional
public void save(Vehicle v) {
em.persist(v);
}
}
I got this error, it was a big headache until I figured out why.. Like it's saying
object references an unsaved transient instance // Read it again
Actual reason, your object - here foreign key mapping object is refering to a value which not available (not available in the table at time of doing dao operation) in the primary key field of the table which holds the primary key. So you've to perform operation on primary key table before performing operation on model class which holds the foreign key..
If you get confused by above paragraph, then I'll make it short and sweet
Your foreign key is referring a value which is not available in the primary key field
Try sysout
the foreign key's value by
System.out.println(modelClassObject.getForeignKeyGetter().getId());
I'm sure it'll return either 0 or a value which is not available in the primary key field which the foreign key is referring.
You can use cascading or persist both entities in a single transaction:
@Transactional
void savePersonVehiclePair(Person person, Vehicle vehicle){
personDao.save(person);
vehicleDao.save(vehicle);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With