hibernate-如何使用分离的子对象保存父对象
我正在从UI发送一个对象。将使用对现有子对象的引用创建此对象 这是这种关系的简单说明hibernate-如何使用分离的子对象保存父对象,hibernate,jpa,orm,Hibernate,Jpa,Orm,我正在从UI发送一个对象。将使用对现有子对象的引用创建此对象 这是这种关系的简单说明 class ParentEntity { @Id Long id; @ManyToOne(fetch = FetchType.LAZY) private ChildEntity child; } class ChildEntity { @Id Long id; } ChildEntity child = new ChildEntity(); child.
class ParentEntity {
@Id
Long id;
@ManyToOne(fetch = FetchType.LAZY)
private ChildEntity child;
}
class ChildEntity {
@Id
Long id;
}
ChildEntity child = new ChildEntity();
child.setId(1);
//parentEntity is created based on data sent from UI
parentEntity.setChild(child);
当我保存这个对象时,Hibernate给我“org.Hibernate.TransientPropertyValueException:对象引用了一个未保存的临时实例”
我不必拯救一个孩子,因为我根本不改变孩子。只需要在父表中保存子id
我尝试过使用几个CascadeType,但没有一个有效。您必须决定如何将ChildEntity持久化为ParentEntity
class ParentEntity {
@Id
Long id;
//To directly load/insert/update childId only
@Column("child_id")
private Long childId;
// To load the child entity with parent, Note that insertable/updatable MUST be false
// as we are inserting/updating = true by default on childId column mapping
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "child_id", insertable = false, updatable = false)
private ChildEntity child;
}
parentEntity.setChildId(childId);
在您使用new关键字创建子实体时,Hibernate将始终认为它是独立的,并试图持久化。 只需使用子对象的代理即可:
parentEntity.setChild(entityManager.getReference(ChildEntity.class, childId));
这里的要点是使用:
获取一个实例,该实例的状态可能是延迟获取的
Hibernate将创建只包含id的代理,而不进入数据库。我也不想从数据库中选择子项并设置为父项,只是为了保存而不出错。如果必须的话,我会的。但是……谢谢。这个解决方案可以工作,但它仍然从数据库中选择子实体。我可以看到hibernate选择日志,当它持久化父级时。这是预期的行为吗?不,不应该加载。您是否明确禁用了
ChildEntity
(@Proxy(lazy=false)
)的代理?如果没有,您能显式启用它(用@Proxy
注释实体)并重试吗?或者,ChildEntity
classfinal
?这是完美的工作解决方案。使用getReference(),它不会检索子对象以保存父对象。我的问题的原因是,我的应用程序在持久化后刷新实体,并从父实体中拉出子实体以将更新的数据返回到UI。在这个时候,这是检索。对不起,我弄糊涂了。无论如何,我需要一个解决我的情况的方法。我还没有尝试过这个方法,但我认为它会奏效。但是,使用此解决方案,在检索父对象时,我不应该获取子对象。更新了带有注释的答案后,您仍然可以使用父对象加载子对象,但您必须决定不通过对象插入/更新子对象,因为您决定仅通过childId插入/更新。如果要同时按对象和id保存子对象,然后,您需要一个自定义拦截器,通过注释您的setter,如果设置了id,它可以加载和设置对象,反之亦然,如果设置了对象,则设置id。