Skip to content

Field access methods are not called when persisting Java 16 records #1138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
hajdamak opened this issue Jan 20, 2022 · 8 comments
Closed

Field access methods are not called when persisting Java 16 records #1138

hajdamak opened this issue Jan 20, 2022 · 8 comments
Labels
status: invalid An issue that we don't feel is valid

Comments

@hajdamak
Copy link

When new Java record is persisted using repository's save method field access methods of the record are not called to read state of the passed record.

Minimal reproducible example: hajdamak/spring-data-jdbc-record-access
Requires Maven and JDK17.
Call mvn spring-boot:run .
Relevant output:

Saving record ...
Constructor is accessed: (null, 0, test)
Constructor is accessed: (5f5b5ea0-3c8c-4ea3-88d1-b02142d2b9b3, 1, test)
Constructor is accessed: (5f5b5ea0-3c8c-4ea3-88d1-b02142d2b9b3, 1, test)
@schauder
Copy link
Contributor

I'd assume this is probably a commons issue. What do you think @mp911de ?

@mp911de
Copy link
Member

mp911de commented Jan 21, 2022

While I agree with @schauder that this is an aspect of Spring Data Commons, everything works as designed. Spring Data uses field access by default. If you want Spring Data to use property accessors, please use the @AccessType annotation.

@mp911de mp911de closed this as completed Jan 21, 2022
@mp911de mp911de added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged labels Jan 21, 2022
@hajdamak
Copy link
Author

@mp911de Is there a way to set PROPERTY access for all entities in one place except setting @AccessType annotation on interface implemented by all entities?

@mp911de
Copy link
Member

mp911de commented Jan 24, 2022

There's no global flag to switch to property accessors for all properties. You could wrap PersistentProperty in the MappingContext and overwrite usePropertyAccess() to achieve that. What's your motivation for using property accessors?

@hajdamak
Copy link
Author

hajdamak commented Jan 24, 2022

@mp911de To avoid reflection and have standard java calls.

@mp911de
Copy link
Member

mp911de commented Jan 24, 2022

Spring Data generates bytecode that uses method handles to interact with fields and you get the same performance as with native method calls. Having standard calls to methods would raise the general question of why using an object-mapper in the first place instead of providing your own Converters.

@hajdamak
Copy link
Author

hajdamak commented Jan 24, 2022

I suppose I wanted to have cake and eat it too. ;-) Have standard calls and at the same time avoid manual Converter implementation. But I guess if fields are accessed using generated bytecode then all performance benefits are already in. And Java is not expressive enough to have standard calls without manual Converter implementation and without additional bytcode magic.

@mp911de
Copy link
Member

mp911de commented Jan 24, 2022

There are efforts to optimize these accesses even more by generating Java code ahead of time with Spring Native/Spring AOT. These efforts could help to avoid runtime class generation in the first place but performance-wise it would lead to the same profile and it would not change the amount of classes loaded at runtime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

4 participants