Skip to content

MappingException when calling a modifying query method that returns kotlin.Unit #421

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
ada-waffles opened this issue Jul 30, 2020 · 2 comments
Labels
type: bug A general bug

Comments

@ada-waffles
Copy link
Contributor

Modifying queries can be declared as returning Void if the result count information is not needed, as shown here. The equivalent declaration in Kotlin would be to use Unit. Currently, Spring Data R2DBC does not recognize the Unit type and attempts to convert the affected row count to Unit as if it were a projection, resulting in:

org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for type class java.lang.Integer!

An example repository method that is affected:

/** Deletes the association from [userId] to [associatedUserId], if it exists */
@Modifying
@Query("DELETE FROM user_association WHERE user_id = :userId AND associated_user_id = :associatedUserId")
suspend fun deleteUserAssociation(userId: Int, associatedUserId: Int)

A workaround is to simply use the Java Void type:

/** Deletes the association from [userId] to [associatedUserId], if it exists */
@Modifying
@Query("DELETE FROM user_association WHERE user_id = :userId AND associated_user_id = :associatedUserId")
suspend fun deleteUserAssociation(userId: Int, associatedUserId: Int): Void

I believe I've tracked this down to AbstractR2dbcQuery#getExecutionToWrap and plan to attempt a PR.

ada-waffles added a commit to ada-waffles/spring-data-r2dbc that referenced this issue Jul 30, 2020
….Unit.

Added check for kotlin.Unit to AbstractR2dbcQuery#getExecutionToWrap. This case is essentially equivalent to a return type of Void, but the singleton Unit instance needs to be returned instead of discarding the result entirely.

It was also necessary to add a check to R2dbcQueryMethod#getEntityInformation, as otherwise a PersistentEntity is created for Unit, which leads to a new instance being created via reflection down the pipeline (which is probably not a thing that should happen).

Added AbstractR2dbcQueryUnitTests to test the functionality surrounding the main change. Also added integration tests surrounding modifying query return types.
@mp911de
Copy link
Member

mp911de commented Jul 31, 2020

Thanks for reporting the issue. Returning Unit should be no different from Void handling. We probably need some changes in Spring Data Commons to consider Unit also a primitive type.

@mp911de
Copy link
Member

mp911de commented Jul 31, 2020

I filed DATACMNS-1779 to provide void type detection. Looking at the pull request, we can simplify it by quite a bit.

@mp911de mp911de added the type: bug A general bug label Jul 31, 2020
@mp911de mp911de added this to the 1.1.3 (Neumann SR3) milestone Jul 31, 2020
mp911de added a commit that referenced this issue Jul 31, 2020
…Unit.

We now discard results for suspended query methods if the return type is kotlin.Unit.

Related ticket: DATACMNS-1779

Original pull request: #422.
mp911de pushed a commit that referenced this issue Jul 31, 2020
Added check for kotlin.Unit to AbstractR2dbcQuery#getExecutionToWrap. This case is essentially equivalent to a return type of Void, but the singleton Unit instance needs to be returned instead of discarding the result entirely.

It was also necessary to add a check to R2dbcQueryMethod#getEntityInformation, as otherwise a PersistentEntity is created for Unit, which leads to a new instance being created via reflection down the pipeline (which is probably not a thing that should happen).

Original pull request: #422.
mp911de added a commit that referenced this issue Jul 31, 2020
Simplify tests. Use ReflectionUtils.isVoid(…) where possible and simplify isVoid(…) flows.

Original pull request: #422.
mp911de added a commit that referenced this issue Jul 31, 2020
…Unit.

We now discard results for suspended query methods if the return type is kotlin.Unit.

Related ticket: DATACMNS-1779

Original pull request: #422.
mp911de pushed a commit that referenced this issue Jul 31, 2020
Added check for kotlin.Unit to AbstractR2dbcQuery#getExecutionToWrap. This case is essentially equivalent to a return type of Void, but the singleton Unit instance needs to be returned instead of discarding the result entirely.

It was also necessary to add a check to R2dbcQueryMethod#getEntityInformation, as otherwise a PersistentEntity is created for Unit, which leads to a new instance being created via reflection down the pipeline (which is probably not a thing that should happen).

Original pull request: #422.
mp911de added a commit that referenced this issue Jul 31, 2020
Simplify tests. Use ReflectionUtils.isVoid(…) where possible and simplify isVoid(…) flows.

Original pull request: #422.
@mp911de mp911de closed this as completed Jul 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants