【发布时间】:2026-02-04 11:10:02
【问题描述】:
我正在将 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();
}
注意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());
}
我实际上希望在调用userRepo.save(user) 时会引发异常,但这并没有发生。相反,最终的 assertEquals() 失败了,这意味着 UUID 实际上正在更新。
这是预期的行为吗?有什么方法可以防止 UUID 被更改?
【问题讨论】:
-
它没有更新,你的测试有缺陷。也不例外,在保存/更新对象时,该字段将被静默忽略。数据库中没有任何变化。您的测试的问题是所有事情都发生在一个事务中,因此只有一个一级缓存(即
EntityManager)。user和user2对象是同一个对象(user == user2应该返回true)。您的最后一个断言是错误的,因为您更改了User对象的内存表示。不是数据库之一。您想使用普通查询来测试它。
标签: java spring hibernate jpa spring-data-jpa