Skip to content

@Table class supports Record (or AllArgsConstructor), but does not support using it with @Transient. #3256

Closed as not planned
@seminchoi

Description

@seminchoi

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:

No property isNew found on entity class com.sem.simpler2dbcpersistableexample.Sample to bind constructor parameter to
org.springframework.data.mapping.MappingException: No property isNew found on entity class com.sem.simpler2dbcpersistableexample.Sample to bind constructor parameter to
	at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:69)
	at org.springframework.data.relational.core.conversion.MappingRelationalConverter$ConvertingParameterValueProvider.getParameterValue(MappingRelationalConverter.java:1244)
	at org.springframework.data.mapping.model.ValueExpressionParameterValueProvider.getParameterValue(ValueExpressionParameterValueProvider.java:56)
	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.relational.core.conversion.MappingRelationalConverter.read(MappingRelationalConverter.java:462)
	at org.springframework.data.relational.core.conversion.MappingRelationalConverter.readAggregate(MappingRelationalConverter.java:357)
	at org.springframework.data.relational.core.conversion.MappingRelationalConverter.readAggregate(MappingRelationalConverter.java:320)
	at org.springframework.data.relational.core.conversion.MappingRelationalConverter.read(MappingRelationalConverter.java:307)
	at org.springframework.data.relational.core.conversion.MappingRelationalConverter.project(MappingRelationalConverter.java:197)
	at 
...

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.
Therefore, this issue does not occur only with records, but also with classes that only have a constructor that takes a field annotated with @Transient as an argument.

The issue can be reproduced at https://github.com/seminchoi/r2dbc-transient-issue

If this is supported, I believe it could be useful with compact constructor of Record.
So, I was wondering if this behavior is intentional or if not, 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 provide me with some guidance on which packages or classes I should check and modify?

Metadata

Metadata

Assignees

No one assigned

    Labels

    for: stackoverflowA question that's better suited to stackoverflow.com

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions