Skip to content

io.r2dbc.spi.Parameter not considered a simple type #1696

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
rsmidt opened this issue Dec 11, 2023 · 11 comments
Closed

io.r2dbc.spi.Parameter not considered a simple type #1696

rsmidt opened this issue Dec 11, 2023 · 11 comments
Labels
type: bug A general bug

Comments

@rsmidt
Copy link

rsmidt commented Dec 11, 2023

I'm currently struggling to use a simple tsrange in a template entity insert.

Reading is fine, as I can utilize a simple Converter<String, MyTsRangeType>. But doing the same for writing (Converter<MyTsRangeType, String>) does not work:

column "my_column" is of type tsrange but expression is of type character varying

Is there a proper way for dealing with ranges?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 11, 2023
@mp911de
Copy link
Member

mp911de commented Dec 12, 2023

You need to apply casting on the SQL level. Alternatively, you can provide a converter from MyTsRangeType to Parameter if you can provide the Postgres Type OID.

The driver doesn't provide any value objects for ranges, therefore you must bind the value as string and tell the driver to use tsrange

R2DBC's Parameters.in(…) along with the driver's PostgresTypes.lookupType("tsrange") should return you the type descriptor required for Parameters.in(myTsRangeType.toString(), typeDesc).

Let me know whether this helps.

@mp911de mp911de added the status: waiting-for-feedback We need additional information before we can continue label Dec 12, 2023
@rsmidt
Copy link
Author

rsmidt commented Dec 12, 2023

Hey @mp911de, thanks for your swift reply.

Ideally, I could avoid doing it on the SQL level and fully rely on the abstractions already there. Following your feedback, I tried the following (excuse the Kotlin):

// Taken from PostgresTypes.from(...).lookupType("tsrange")
private val PG_RANGE_TYPE = PostgresTypes.PostgresType(3908, 3908, 3909, 3909, "tsrange", "R")

@WritingConverter
object TsRangeSerializer : Converter<TsRange, Parameter> {
    override fun convert(source: TsRange): Parameter {
        return Parameters.`in`(PG_RANGE_TYPE, source.toPostgresValue())
    }
}

fun TsRange.toPostgresValue(): String =
    "[\"${start.format(PG_TIMESTAMP_FORMATTER)}\",\"${end.format(PG_TIMESTAMP_FORMATTER)}\"]"

Unfortunately, now it fails with an error I don't fully comprehend:

java.lang.IllegalArgumentException: Cannot encode null parameter of type io.r2dbc.spi.Parameters$InParameter
at io.r2dbc.postgresql.codec.DefaultCodecs.encodeNull(DefaultCodecs.java:302)

I don't understand why it tries to bind to null?

@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 Dec 12, 2023
@mp911de
Copy link
Member

mp911de commented Dec 12, 2023

null values are not using the Converter, instead, we use the property (converted) type and not a value.

You could register a BeforeSaveCallback and post-process the OutboundRow to replace the value with a proper Parameters.in(…) null value wrapped in a Spring org.springframework.r2dbc.core.Parameter.

@rsmidt
Copy link
Author

rsmidt commented Dec 12, 2023

Maybe I'm misunderstanding something, but the value is not null in this case. The column itself is actually not nullable. That's why I expect it will never try to bind anything nullish.

@mp911de
Copy link
Member

mp911de commented Dec 12, 2023

Can you provide the full stack trace and a minimal sample (SQL, domain types, converters, test)? Happy to debug the issue here once I have a bit of code that gets me started.

@rsmidt
Copy link
Author

rsmidt commented Dec 12, 2023

Thank you! Here's the repo: https://github.com/rsmidt/spring-data-r2dbc-range-types

It's written in Kotlin. I can change it to Java if required. It's expecting Postgres running on port 5432, configured in the application.properties (there's also a docker-compose.yml).

Please let me know if I can help in any way.

@mp911de mp911de added type: bug A general bug and removed status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged labels Dec 13, 2023
@mp911de mp911de changed the title How to use range types? io.r2dbc.spi.Parameter not considered a simple type Dec 13, 2023
@mp911de mp911de transferred this issue from spring-projects/spring-data-r2dbc Dec 13, 2023
@mp911de
Copy link
Member

mp911de commented Dec 13, 2023

I moved this ticket into Spring Data Relational as Spring Data R2DBC is part of the Relational project.

This is a bug where we attempt an entity conversion by extracting the identifier.

@mp911de mp911de added this to the 3.1.7 (2023.0.7) milestone Dec 13, 2023
mp911de added a commit that referenced this issue Dec 13, 2023
We now consider R2DBC's Parameter as simple type to avoid entity handling.

Closes #1696
mp911de added a commit that referenced this issue Dec 13, 2023
We now consider R2DBC's Parameter as simple type to avoid entity handling.

Closes #1696
@mp911de
Copy link
Member

mp911de commented Dec 13, 2023

That's fixed now. Care to upgrade to 3.2.1-SNAPSHOT of spring-data-r2dbc and retest whether the fix addresses your problem?

@rsmidt
Copy link
Author

rsmidt commented Dec 13, 2023

Stupid question, but where is the snapshot being published? If I try to override it like this:

    implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
    implementation("org.springframework.data:spring-data-r2dbc:3.2.1-SNAPSHOT")

It fails:

Could not find org.springframework.data:spring-data-r2dbc:3.2.1-SNAPSHOT.
Required by:
project :
Could not find org.springframework.data:spring-data-r2dbc:3.2.1-SNAPSHOT.
Required by:
project : > org.springframework.boot:spring-boot-starter-data-r2dbc:3.2.0

@mp911de
Copy link
Member

mp911de commented Dec 13, 2023

No worries, the repo is at https://repo.spring.io/snapshot. The Maven declaration would be:

<repository>
  <id>spring-snapshot</id>
  <name>Spring Snapshot Repository</name>
  <url>https://repo.spring.io/snapshot</url>
</repository>

@rsmidt
Copy link
Author

rsmidt commented Dec 13, 2023

Yes! It's working now directly using the entity template.

Thank you very much for the swift fix, it's much appreciated.

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

3 participants