我正在将 Spring Boot 应用程序从 Java 11 更新到 Java 17,并将 Spring Boot
2.7.18
更新到 3.2.4
,并运行测试时出现错误。
所以,我有一个名为
WorkloadDAO
的实体,如下所示:
@Entity
@Table(name = "workloads")
@IdClass(WorkloadId.class)
public class WorkloadDAO {
@Id
@NonNull()
private String id;
@Id
@Column(name = "created_at", insertable = false, updatable = false, columnDefinition = "TIMESTAMP")
private LocalDateTime createdAt;
// more attributes
@PrePersist
protected void onCreate() {
createdAt = LocalDateTime.now();
}
createdAt
属性将始终以空值接收,并且在将实例保存到数据库之前,将通过用onCreate()
注释的@PrePersist
方法设置它。
正如您在注释
@IdClass(WorkloadId.class)
中看到的那样,我将WorkloadId
设置为此类的id。 WorkloadId
类是这样的:
public class WorkloadId implements Serializable {
private String id;
private LocalDateTime createdAt;
}
到目前为止,在测试之前一切都很好。 例如,我正在运行这个测试:
@Test
void testSaveWorkload() {
String id = "someid";
WorkloadDAO dao = WorkloadDAO.builder()
.id(id)
.build();
WorkloadDAO response = repository.saveAndFlush(dao);
assertThat(repository.findById(WorkloadId.builder()
.id(id)
.createdAt(response.getCreatedAt())
.build()))
.get()
.extracting("createdAt").isNotNull();
}
在更新Java和Spring Boot之前,此测试运行成功。但现在,我收到以下错误:
org.springframework.orm.jpa.JpaSystemException: identifier of an instance of com.adevinta.delivery.workloadapi.data.WorkloadDAO was altered from WorkloadId(id=someid, createdAt=2024-03-28T12:26:34.355098) to WorkloadId(id=someid, createdAt=null)
你能帮我理解为什么我会得到这个吗? 谢谢!
我期望发生的是测试工作,无需事先设置字段
createdAt
。
您的问题是由于createdAt上的
insertable = false
属性造成的。 @PrePersist
中分配的值将不会作为结果保存到数据库中。通常,“创建于”字段可插入但不可更新,“修改于”字段反之亦然。尝试将createdAt列定义更改为:
@Column(name = "created_at", insertable = true, updatable = false, columnDefinition = "TIMESTAMP")
.