0

I would like to generate a query with my R2dbcRepository. In Spring Data JPA the documentation says to use #{#entityName} to get an Entity if a repository is generic, however I can't find the equivalent in R2DBC.

I'm using a H2 in memory database: r2dbc:h2:mem:///~/db/testdb

R2dbcRepository

public interface UUIDRepository<Model, IdType> extends R2dbcRepository<Model, IdType> {

    Mono<Model> findByIdAndUserUUID(Long id, UUID uuid);

    @Query("SELECT * FROM #{#entityName} WHERE model.id = :id AND (model.user_uuid = :uuid OR model.user_uuid IS NULL)")
    Mono<Model> findByIdAndUserUUIDOrUserUUIDIsNull(@Param("id") Long id, @Param("uuid") UUID uuid);
}

Exception

Caused by: io.r2dbc.spi.R2dbcBadGrammarException: [42000] [42000] Syntax error in SQL statement "FROM [*]#{#entityName} model WHERE model.id = $1 AND (model.user_uuid = $2 OR model.user_uuid IS NULL)"; SQL statement:

I know the syntax for the rest of the query is correct as if I replace #{#entityName} with a table name it works fine.

How can I insert the entity name in a query when using R2DBC?

Michael
  • 3,411
  • 4
  • 25
  • 56

1 Answers1

1

How can I insert the entity name in a query when using R2DBC?

Short answer, you don't.

R2DBC don't have the concept of entities in the same sense as JPA does. You write native queries when you write queries for R2DBC.

So, it's not JPQL and therefore the query language don't have any concept of an entity representation from your code.

However the repository still supports an auto mapping from your database resulting column information per row to a list of (data) objects. That's the reason why it works when you replace your entity name with the table name.

snap
  • 1,598
  • 1
  • 14
  • 21
  • I see! Is the best approach likely going to be passing the table name to the parent repository? I was just trying to avoid this to keep it tidier but if needed I'll do it this way. – Michael Aug 02 '22 at 19:28
  • 1
    I don't know exactly what you mean with the term parent repository? Do you mean parent because other repositories will extend from this one? Or do you mean the repository classes your repo is inherited from? So, you have to use the table name inside your query. And all underlying code sections which does the repository logic will be using this query. – snap Aug 02 '22 at 19:31
  • I mean parent as other repositories will extend this one but have different models. Just wondering as annotations require a constant when inserting strings into them so I can't dynamically create the query. I'll have a look and see how I get on. Thank you for your help! – Michael Aug 02 '22 at 19:37
  • 1
    Yes i guess the annotation approach is quite limited for such generic logic. But. you could create a customized repository: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations Basically you have one more interface which is inherited by your repository. And you have one implementation class for this interface. In this one you could do programmatic coding. For R2DBC i have used the DatabaseClient class for this purpose. (but you could use anything which is compatible with R2DBC here) – snap Aug 02 '22 at 19:46
  • Ah excellent. I'll check that out thank you! It's a matter of getting familiar with the different approaches. – Michael Aug 02 '22 at 19:52