Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
hibernate-如何使用分离的子对象保存父对象_Hibernate_Jpa_Orm - Fatal编程技术网

hibernate-如何使用分离的子对象保存父对象

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.

我正在从UI发送一个对象。将使用对现有子对象的引用创建此对象

这是这种关系的简单说明

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

  • 若您总是希望仅通过id持久化子对象,那个么您可以这样做,并且如果它的子对象无效,FK将阻止您

    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);
    
  • 但是,如果要使用现有模型持久化子对象,其中子对象映射为对象,则必须获取子对象并对其进行设置。 parentEntity.setChild(childRepository.findOne(childId)) 或 您还可以为getOrCreateChild编写一个自定义DAO方法,该方法可以创建一个新的子对象,或者查找现有的子对象并返回它,这样您就可以首先持久化子对象


  • 在您使用new关键字创建子实体时,Hibernate将始终认为它是独立的,并试图持久化。 只需使用子对象的代理即可:

    parentEntity.setChild(entityManager.getReference(ChildEntity.class, childId));
    
    这里的要点是使用:

    获取一个实例,该实例的状态可能是延迟获取的


    Hibernate将创建只包含id的代理,而不进入数据库。

    我也不想从数据库中选择子项并设置为父项,只是为了保存而不出错。如果必须的话,我会的。但是……谢谢。这个解决方案可以工作,但它仍然从数据库中选择子实体。我可以看到hibernate选择日志,当它持久化父级时。这是预期的行为吗?不,不应该加载。您是否明确禁用了
    ChildEntity
    @Proxy(lazy=false)
    )的代理?如果没有,您能显式启用它(用
    @Proxy
    注释实体)并重试吗?或者,
    ChildEntity
    class
    final
    ?这是完美的工作解决方案。使用getReference(),它不会检索子对象以保存父对象。我的问题的原因是,我的应用程序在持久化后刷新实体,并从父实体中拉出子实体以将更新的数据返回到UI。在这个时候,这是检索。对不起,我弄糊涂了。无论如何,我需要一个解决我的情况的方法。我还没有尝试过这个方法,但我认为它会奏效。但是,使用此解决方案,在检索父对象时,我不应该获取子对象。更新了带有注释的答案后,您仍然可以使用父对象加载子对象,但您必须决定不通过对象插入/更新子对象,因为您决定仅通过childId插入/更新。如果要同时按对象和id保存子对象,然后,您需要一个自定义拦截器,通过注释您的setter,如果设置了id,它可以加载和设置对象,反之亦然,如果设置了对象,则设置id。