Description
When using Persistable
with a record class in an R2DBC Data Repository, I found that the record does not work properly with the @Transient
annotation.
Here is a sample code:
@Table("sample")
@Builder
public record SampleRecord(
@Id
UUID id,
@Transient
boolean isNew
) implements Persistable<UUID> {
@Override
public UUID getId() {
return id;
}
@Override
public boolean isNew() {
return isNew;
}
}
public interface SampleRecordRepository extends R2dbcRepository<SampleRecord, UUID> {
}
And the test code:
@SpringBootTest
class Simpler2dbcPersistableExampleApplicationTests {
@Autowired
SampleRecordRepository sampleRecordRepository;
@Test
void recordTest() {
UUID sampleId = UUID.randomUUID();
SampleRecord sample = SampleRecord.builder()
.id(sampleId)
.isNew(true)
.build();
sampleRecordRepository.save(sample)
.then(sampleRecordRepository.findById(sampleId))
.block();
}
}
Running this test produces the following error:
Required property name not found for class com.sem.simpler2dbcpersistableexample.Sample2
java.lang.IllegalStateException: Required property name not found for class com.sem.simpler2dbcpersistableexample.Sample2
at org.springframework.data.mapping.PersistentEntity.getRequiredPersistentProperty(PersistentEntity.java:190)
at org.springframework.data.mapping.model.InstantiationAwarePropertyAccessor$1.getParameterValue(InstantiationAwarePropertyAccessor.java:115)
at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.extractInvocationArguments(ClassGeneratingEntityInstantiator.java:301)
at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:273)
at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:98)
at org.springframework.data.mapping.model.InstantiationAwarePropertyAccessor.setProperty(InstantiationAwarePropertyAccessor.java:106)
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.potentiallySetId(MappingR2dbcConverter.java:471)
at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.lambda$populateIdIfNecessary$2(MappingR2dbcConverter.java:451)
After debugging the issue, I found that when creating the entity without using the default constructor, no additional actions are performed, such as injecting null values or default values, into fields annotated with @transient.
The same issue occurs with a class that only has an @AllArgsConstructor
.
The issue can be reproduced at https://github.com/seminchoi/r2dbc-transient-issue
So, I was wondering if this behavior is intentional or if there are any plans to support it.
Additionally, I would like to know if I can contribute to fixing this issue. If so, could you guide me on which parts of the code I should modify?