当我使用merge时,我希望hibernate将非空值复制到持久化实体并更新数据库。因此,在下面的use-case中,我预计合并将使lastName保持值Last_0并将firstName更改为值First_1

但实际上,hibernate只是更新,这意味着lastName在代码执行后变为null

    @Transactional
    public void create()  {
        SomeEntity create = new SomeEntity();
        create.setFirstName("First_0");
        create.setLastName("Last_0");
        this.getSession().save(create);
        //now in the database id:1, firstName:First_0, lastName:Last_0
   }


   @Transactional
    public void merge()  {
        SomeEntity merge = new SomeEntity();
        merge.setId(1);
        merge.setFirstName("First_1");
        this.getSession().merge(merge);
         // now in the database id:1, firstName:First_1, lastName:null
    }
    create();
    merge();

我希望lastName具有Last_0的值,因为它正在合并。但它是空的。

谢谢

分析解答

您对Hibernate的merge()在实践中的实现方式感到困惑。在这种情况下,merge()通过SQL UPDATE在引擎盖下实现,意思如下:

UPDATE some_entity
SET
    firstName = 'First_1',
    lastName = NULL
WHERE
    id = 1;

也就是说,它将覆盖所有分区实体碰巧拥有的所有字段值。请注意,如果不存在具有此主键id=1的记录,那么Hibernate将完成INSERT,而不是更新。

如果你想从实体的原始值开始,那么你应该使用get:

SomeEntity merge = (SomeEntity) this.getSession().get(SomeEntity.class, 1);
merge.setFirstName("First_1");
this.getSession().merge(merge);

现在原始值将是"stick,",除了第一个名称,它被覆盖到其他名称。