Skip to content

Add camelCase to snake_case fallback for native query projections #3462

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
cjacky475 opened this issue May 7, 2024 · 6 comments
Closed

Add camelCase to snake_case fallback for native query projections #3462

cjacky475 opened this issue May 7, 2024 · 6 comments
Assignees
Labels
type: enhancement A general enhancement

Comments

@cjacky475
Copy link

cjacky475 commented May 7, 2024

Hello, I have my Friend repository class from friend Modulith module:

@Repository
interface FriendRepository: JpaRepository<Friend, Long> {

For testing purposes I will create simple function to get users within Friend repository:

 @Query(value = "SELECT * FROM users WHERE users.id = 558978864945139712 ", nativeQuery = true)
 fun getUsers(): Optional<UserProjection>

The interface for the User entity is:

interface UserProjection {
    fun getId(): Long
    fun getUsername(): String
    fun getEmail(): String
    fun getFullName(): String
}

The User entity has these fields (others emitted):

val email: String = "",
var fullName: String = "",

However, the REST API returns null on fullName field.

How does that work exactly? Why my projection fails for camel case fields when projection class (in this instance UserProjection is in different module?

--------------------- EDIT ---------------------

Okay, so I finally understood what was happening. I had to create two projection classes, one for functions that use native query and one for those who do not.

For functions that use native query, interface projection for camel case fields must be specified as:

 @JsonProperty("fullName")
 fun getFull_name(): String

for projection that do not use native queries, I can use:

fun getFullName(): String

I still do not understand why is that. Is there a more appropriate solution for using only single projection so it would satisfy both native and non native queries? Cheers.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label May 7, 2024
@cjacky475 cjacky475 changed the title Spring projection fails for camel case fields when repository extends custom interface Spring projection fails for camel case fields when projection class is from different module May 8, 2024
@cjacky475 cjacky475 changed the title Spring projection fails for camel case fields when projection class is from different module Spring projection needs different function name for camel case fields when using native query May 8, 2024
@quaff
Copy link
Contributor

quaff commented May 11, 2024

By default, Spring Boot configures the physical naming strategy with CamelCaseToUnderscoresNamingStrategy.

The column name is full_name, you could use select full_name as fullName as workaround or switch to another NamingStrategy like org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl.

@cjacky475
Copy link
Author

Hi, @quaff, thanks for the answer.

The column name is full_name, you could use select full_name as fullName as workaround

This would become very inefficient and unmaintainable to write out all individual fields for selection, wouldn't it? SELECT id, full_name as fullName, etc...

switch to another NamingStrategy like org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

But this is not going to change the fact that when using native and non-native queries the return value is interpreted differently? I use PostgreSQL and return values are snake like full_name, also when submitting they have to be snake case.

Cheers.

@quaff
Copy link
Contributor

quaff commented May 13, 2024

But this is not going to change the fact that when using native and non-native queries the return value is interpreted differently? I use PostgreSQL and return values are snake like full_name, also when submitting they have to be snake case.

I agree, It would be great if Spring Data JPA handle it like BeanPropertyRowMapper does in Spring Framework.

https://github.com/spring-projects/spring-framework/blob/19792f9670943687e2497fa90084437c201b3ae8/spring-jdbc/src/main/java/org/springframework/jdbc/core/BeanPropertyRowMapper.java#L277-L295

quaff added a commit to quaff/spring-data-jpa that referenced this issue May 13, 2024
…e for projecting native query

> By default, Spring Boot configures the physical naming strategy with CamelCaseToUnderscoresNamingStrategy.

Then we should convert underscores back to camel case.

Fix spring-projectsGH-3462
quaff added a commit to quaff/spring-data-jpa that referenced this issue May 13, 2024
…e for projecting native query

> By default, Spring Boot configures the physical naming strategy with CamelCaseToUnderscoresNamingStrategy.

Then we should convert underscores back to camel case.

Fix spring-projectsGH-3462
@mp911de
Copy link
Member

mp911de commented May 13, 2024

Please provide a minimal yet complete sample that reproduces the problem.
You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.

@mp911de mp911de added the status: waiting-for-feedback We need additional information before we can continue label May 13, 2024
@mp911de mp911de self-assigned this May 13, 2024
@quaff
Copy link
Contributor

quaff commented May 13, 2024

Please provide a minimal yet complete sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.

You can reproduce it by running the added test in (#3472)

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels May 13, 2024
@mp911de
Copy link
Member

mp911de commented May 13, 2024

There's an easier approach by using @Value("#{target.full_name}") if you want to rename fields.

@mp911de mp911de changed the title Spring projection needs different function name for camel case fields when using native query Add camelCase to snake_case fallback for native query projections May 13, 2024
@mp911de mp911de added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged status: feedback-provided Feedback has been provided labels May 13, 2024
quaff added a commit to quaff/spring-data-jpa that referenced this issue May 13, 2024
…e for projecting native query

> By default, Spring Boot configures the physical naming strategy with CamelCaseToUnderscoresNamingStrategy.

Then we should convert underscores back to camel case.

Fix spring-projectsGH-3462
quaff added a commit to quaff/spring-data-jpa that referenced this issue May 13, 2024
…e for projecting native query

> By default, Spring Boot configures the physical naming strategy with CamelCaseToUnderscoresNamingStrategy.

Then we should convert underscores back to camel case.

Fix spring-projectsGH-3462
mp911de added a commit that referenced this issue May 14, 2024
Tweak naming, simplify implementation.

See #3462
Original pull request: #3472
@mp911de mp911de added this to the 3.3 GA (2024.0.0) milestone May 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
4 participants