r2dbc/r2dbc-h2

Syntax error with SELECT queries

eau-de-la-seine opened this issue · 0 comments

Versions

  • Driver: io.r2dbc:r2dbc-h2:0.8.3.RELEASE
  • Database: H2
  • Java: openjdk version "11.0.6" 2020-01-14
  • OS: Ubuntu 18.04.4 LTS

Current Behavior

According to the Spring R2DBC documentation I can use this syntax (copy/paste from documentation):

@Query("select u from User u")
Stream<User> findAllByCustomQueryAndStream();

Error A

Here the equivalent with my code:

@Query("SELECT u FROM UserEntity u WHERE u.id = :email AND u.hash = :hash")
Mono<UserEntity> findByEmailAndHash(String email, String hash);

Error: Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "USERENTITY" not found; SQL statement:
So the Entity's name isn't supported, I have to use table's name.

Error B

Same example but with table's name:

@Query("SELECT u FROM user u WHERE u.id = :email AND u.hash = :hash")
Mono<UserEntity> findByEmailAndHash(String email, String hash);

Error: Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "U" not found; SQL statement:
So it considers u as a column, because u.* works as expected

Error C

The FROM x syntax:

@Query("FROM user WHERE id = :email AND hash = :hash")
Mono<UserEntity> findByEmailAndHash(String email, String hash);

Error: Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "FROM[*] USER WHERE ID = $1 AND HASH = $2"; SQL statement:
This syntactic sugar where we are omitting SELECT * doesn't work (it doesn't really matter for me, just wanted to tell you)

The only solution which works

The only solution which works is SELECT * :

@Query("SELECT * FROM user WHERE id = :email AND hash = :hash")
Mono<UserEntity> findByEmailAndHash(String email, String hash);

Code

For my Entities I don't use JPA annotations/classes, I use these:

import org.springframework.data.annotation.Id;
import org.springframework.data.domain.Persistable;
import org.springframework.data.relational.core.mapping.Column;

My repository:

import fr.ekinci.project.repository.entity.UserEntity;
import org.springframework.data.r2dbc.repository.Modifying;
import org.springframework.data.r2dbc.repository.Query;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import reactor.core.publisher.Mono;

public interface UserRepository extends ReactiveCrudRepository<UserEntity, String> {
    // See examples shown above
}

Questions

Question 1: Are error A, B and C are expected behaviours or will they be supported with 1.0.0 ?

It doesn't work without @Query:

Mono<UserEntity> findByIdAndHash(String email, String hash);

Error: Caused by: java.lang.UnsupportedOperationException: Query derivation not yet supported!
Question 2: Will "Derived Query Methods" be supported with 1.0.0 ?

Question 3: I have noticed that we are using the $ symbol for placeholders with R2DBC, instead of ? like in JPA, was there a specific reason?

Question 4: Does the org.springframework.transaction.annotation.Transactional annotation on my services' method work when we are using ReactiveCrudRepository or only when we are using org.springframework.data.r2dbc.core.DatabaseClient instance?

Thanks