我有一个简单的一对一关系:
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);
每当我运行应用程序时,我都会遇到以下异常:
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
我尝试在两个订单中保存实体:
personDao.save(person);
vehicleDao.save(vehicle);
和
vehicleDao.save(vehicle);
personDao.save(person);
我得到同样的例外。
我能够通过以下方式解决这个问题:
问题是,是否有更好的解决方案?也许我做了一些根本错误的事情?
以下是(普通)实体和DAO:
@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);
}
}
答案 0 :(得分:2)
我收到了这个错误,直到我弄明白为什么这是一个令人头疼的问题......就像它说的那样
object references an unsaved transient instance // Read it again
实际原因,你的对象 - 这里的外键映射对象是指在保存主键的表的主键字段中不可用的值(在执行dao操作时表中不可用)。因此,在对保存外键的模型类执行操作之前,您必须对主键表执行操作。
如果你对上段感到困惑,那么我会让它变得简短而又甜蜜
您的外键是指主键字段中不可用的值
通过
尝试sysout
外键的值
System.out.println(modelClassObject.getForeignKeyGetter().getId());
我确定它会返回0或外键所指的主键字段中没有的值。
答案 1 :(得分:2)
您可以在单个事务中使用级联或持久化两个实体:
@Transactional
void savePersonVehiclePair(Person person, Vehicle vehicle){
personDao.save(person);
vehicleDao.save(vehicle);
}
答案 2 :(得分:0)
<form:select path="bioData.address.lga.lgaId" id="title" required="required" class="form-control col-md-7 col-xs-12">
<c:forEach items="${lgaList}" var="lga">
<form:option value="${lga.lgaId }"><c:out value="${lga.name}"/></form:option>
</c:forEach>
</form:select>
下面的代码是错误的代码:
<form:select path="bioData.address.lga.lgaName" id="title" required="required" class="form-control col-md-7 col-xs-12">
<c:forEach items="${lgaList}" var="lga">
<form:option value="${lga.lgaId }"><c:out value="${lga.name}"/></form:option>
</c:forEach>
</form:select>
现在工作正常。