休眠生成的字段为空直到刷新

Hibernate Generated fields null until flush

我正在尝试保存具有多个由数据库触发器生成的字段的实体。

public class MyEntity {
    @Id
    @GeneratedValue
    protected UUID id;

    //generated by DB trigger   
    @Generated(value = GenerationTime.ALWAYS)
    @Column(name = "generated_number", insertable = false, updatable = false)
    private String generatedNumber;

    //generated by DB trigger
    @Generated(value = GenerationTime.INSERT)
    @Column(name = "postfix", insertable = false, updatable = false)
    private Integer postfix;

   //other normal fields
}

@Repository
public interface MyRepository extends PagingAndSortingRepository<MyEntity, UUID>, JpaRepository<MyEntity, UUID>

文档指出生成的注释将字段标记为由 DB 填充。 Hibernate 应该从数据库加载生成的数据。

Generated properties are properties that have their values generated by the database. Typically, Hibernate applications needed to refresh objects that contain any properties for which the database was generating values. Marking properties as generated, however, lets the application delegate this responsibility to Hibernate. When Hibernate issues an SQL INSERT or UPDATE for an entity that has defined generated properties, it immediately issues a select to retrieve the generated values.

Properties marked as generated must additionally be non-insertable and non-updateable. Only @Version and @Basic types can be marked as generated.

但是,生成字段的内容直到刷新才加载。

@Transactional
public MyEntity save(MyEntity entity) {
    //save without flush
    //assertions fail
    //MyEntity updated = repository.save(entity);
    //works fine
    MyEntity updated = repository.saveAndFlush(entity);
    assert updated.getGeneratedNumber() != null;
    assert updated.getPostfix() != null;
}

我生成的字段被标记为不可插入和不可更新。它们是基本的 String 类型。我也尝试在它们上面添加一个 @Basic 注释,但它没有帮助。

我错过了什么?

通常由于缓存的原因,实际上是在事务完成时调用数据库。您正在使用 @Transactional 属性,因此该调用在方法的末尾由 flush() 执行,更具体地说是由 commit() 在内部完成。这就是为什么您看不到代码更改并且未生成值的原因 - 在 flush().

之前未完成对数据库的调用