Hibernate updatable = false UUID字段已更新

JBC*_*BCP 9 java spring hibernate jpa spring-data-jpa

我正在使用Spring Data JPA和Hibernate,并且在@Column注释上遇到了updatable = false属性.

我有一个基类用于我的所有@Entity对象,其UUID定义如下:

@MappedSuperclass
@Getter @Setter @EqualsAndHashCode(of= {"uuid"})
public abstract class AbstractEntity implements Persistable<Long> {

    @Id
    @GeneratedValue(strategy = AUTO)
    @Column(unique = true, updatable = false)
    private Long id;

    @Column(unique = true, updatable = false)
    private UUID uuid = UUID.randomUUID();

}
Run Code Online (Sandbox Code Playgroud)

注意updatable = false注释.

为了验证UUID字段实际上是不可更新的,我已经写了这个测试:

@Test
public void testChangeUUID() {

    User user = userRepo.findOne(1L);

    assertNotNull(user);
    assertEquals(USER_UUID, user.getUuid().toString());

    final UUID newUuid = UUID.randomUUID();

    user.setUuid(newUuid);

    user = userRepo.save(user);

    assertEquals(newUuid, user.getUuid());

    User user2 = userRepo.findOne(1L);
    assertNotNull(user2);
    assertEquals("UUID should not have changed", USER_UUID, user2.getUuid().toString());
}
Run Code Online (Sandbox Code Playgroud)

我实际上期待在调用时抛出异常userRepo.save(user),但这不会发生.相反,最终assertEquals()失败,这意味着UUID实际上正在更新.

这是预期的行为吗?有没有办法阻止UUID被更改?

And*_*sne 10

根据文档,该updatable属性决定该列是否是更新语句的一部分.这意味着Hibernate在向数据库发送更新时会忽略它.因此,内存状态和数据库状态将不同.

要验证这一点,请在呼叫前尝试清除会话(逐出) User user2 = userRepo.findOne(1L)

  • 我知道第一部分,但没有意识到Hibernate正在缓存对象。我在测试中的“ findOne()”之前添加了“ entityManager.clear();”,现在它可以正确通过了。感谢您直接暗示该权利。 (2认同)

Z3d*_*d4s 6

虽然最初的问题已经得到解答,但我想向刚接触 Hibernate 的人强调重要的一点强调重要的一点,因为这可能有助于避免一些混乱。

\n\n

Hibernate 5.4 的javadoc 可选元素 Updatable 表示:

\n\n
\n

(可选)该列是否包含在持久性提供程序生成的SQL UPDATE 语句中SQL UPDATE 语句中。

\n
\n\n

如果您使用HQL 或CriteriaUpdate发出更新语句,针对您已注释的字段,您的更新语句将被执行@Column(updatable = false)

\n\n

@Column(updatable = false)当您使用 Hibernate\xe2\x80\x99supdate或 JPA\xe2\x80\x99smerge方法时,该方法有效。

\n\n

不会抛出异常(与例如:不同,@Column(nullable= false)因为它创建了约束...),但生成的更新语句将不包含标记的字段。

\n\n

要了解更多信息,确实必须熟悉 JPA\xe2\x80\x99s 实体生命周期状态以及管理它们的方法,如下图所示。

\n\n

我强烈建议阅读这篇文章,其中详细解释了这一点,并且是所附图片的来源

\n\n

JPA\xe2\x80\x99s 实体生命周期状态

\n