Hibernate TransientPropertyValueException,同时保持实体ID为0的多对一关系

时间:2014-09-26 12:46:47

标签: hibernate jpa oracle11g

在持久存在 Order 对象时,我遇到了一个奇怪的异常 与 deliveryMode 有多对一的关系。

以下是订单对象中定义的映射。

@ManyToOne  
@JoinColumn(name = "DELIVERY_MODE_ID")   
private DeliveryMode deliveryMode;

投放模式已存在于数据库中, 因此无需指定级联。

以下是DeliveryMode类中的双向映射:

@OneToMany(mappedBy = "deliveryMode")
private List<Order> orders;

我在Order对象中设置DeliveryMode,并使用JPA实体管理器将订单保存为:

Order order = new Order();
DeliveryMode deliveryMode = new DeliveryMode();
deliveryMode.setDeliveryModeId(0);
order.setDeliveryMode(deliveryMode);
entityManager.persist(order);

以上代码提供以下异常:

org.hibernate.TransientPropertyValueException: 
object references an unsaved transient instance for given deliveryMode.

deliveryModeId = 0的条目已存在于数据库中。 当我尝试使用除0以外的deliveryModeId保存条目时 上面的片段工作正常。

谢谢:)

2 个答案:

答案 0 :(得分:0)

在您的代码中:

Order order = new Order();
DeliveryMode deliveryMode = new DeliveryMode();
deliveryMode.setDeliveryModeId(0);
order.setDeliveryMode(deliveryMode);
entityManager.persist(order);

您已创建新的Order对象和新的DeliveryMode对象,然后将DeliveryMode分配给您的Order对象。然后你将Order对象传递给hibernate并要求它保存它(或者保留它)。

现在,hibernate从persist方法获取对象,该方法是Order对象,并将其放在会话缓存中(第一级缓存)。现在,在保存此Order时,它会观察到父Order对象具有子DeliveryMode对象。因此,它会检查其会话(第一级缓存),看看它是否有DeliveryModeid对象作为0,您已在代码中设置了DeliveryMode。然后它发现id 0没有DeliveryMode这样的对象,因此它会抛出一个异常,说明在保存Order之前必须保存org.hibernate.TransientPropertyValueException: object references an unsaved transient instance for given deliveryMode. 对象对象。这就是例外情况:

DeliveryMode

因此,要解决此问题,您需要从数据库中获取所需id 0的{​​{1}}对象。一旦获得对象,该对象将处于休眠的会话缓存中。现在将此DeliveryMode对象分配给Order对象,然后保存您的Order对象。

正如Ahishs在评论中所建议的那样,请查看以下链接:java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException

答案 1 :(得分:0)

终于得到了解决方案。我正在使用Id的原始短片。 将其转换为包装解决了这个问题。 在使用原始数据类型的情况下,似乎hibernate不接受0作为ID。 谢谢大家:))

使用原始类型时,主键id默认设置为0,如果0是实体对应表中实际id列的值,则hibernate会混淆。