I'm updating my Spring Boot application from Java 11 to Java 17, and Spring Boot 2.7.18 to 3.2.4, and running the tests I'm getting an error.
So, I have a entity called WorkloadDAO like this:
@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();
}
The createdAt attribute will always be received with null value, and it will be set by the onCreate() method annotated with @PrePersist before save the instance in the database.
As you can see in the annotation @IdClass(WorkloadId.class), I'm setting WorkloadId as the id of this class. The WorkloadId class is like this:
public class WorkloadId implements Serializable {
private String id;
private LocalDateTime createdAt;
}
So far, so good until the test. For example, I'm running this test:
@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();
}
Before updating Java and Spring Boot, this test was running successfully. But now, I'm getting the following error:
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)
Can you help me to understand why I'm getting this? Thanks!
What I expect to happen is the test works, without setting the field createdAt beforehand.
Your issue is due to the
insertable = falseattribute on createdAt. The value assigned in@PrePersistwill not be saved to the database as a result. Typically 'created at' fields are insertable but not updatable and visa versa for 'modified at' fields. Try changing the createdAt column definition to:@Column(name = "created_at", insertable = true, updatable = false, columnDefinition = "TIMESTAMP").