'R2DBC - IllegalArgumentException: Cannot encode parameter of type java.util.Date
I'm learning Reative jdbc with R2DBC MySQL. I have a repository like this:
public interface VerificationTokenRepository extends ReactiveCrudRepository<VerificationToken,Long> {
The VerificationToken class looks like this:
@Table
public class VerificationToken {
@Id
private final Long id;
@Column
private final String code;
@Column
private final Date validUntil;
@Column
private boolean used;
@Column
private Long userId;
@Column
private Long verificationTokenType;
The script to create the table is this one:
create table verification_token (
id int unsigned not null AUTO_INCREMENT,
code varchar(36) not null,
valid_until datetime not null,
used boolean not null,
verification_token_type_id int unsigned not null,
user_id int unsigned,
PRIMARY KEY (id),
constraint verification_token_type_fk FOREIGN KEY (verification_token_type_id) REFERENCES verification_token_type(id),
CONSTRAINT user_id_fk FOREIGN KEY (user_id) REFERENCES user(id)
);
When I execute the method verificationTokenRepository.save the console shows this error:
Caused by: java.lang.IllegalArgumentException: Cannot encode parameter of type java.util.Date
at io.r2dbc.h2.codecs.DefaultCodecs.encode(DefaultCodecs.java:73)
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ SQL "INSERT INTO verification_token (code, valid_until, used, user_id, verification_token_type) VALUES ($1, $2, $3, $4, $5)" [DatabaseClient]
Stack trace:
POM file
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<!-- For testing possibility -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>dev.miku</groupId>
<artifactId>r2dbc-mysql</artifactId>
<version>0.8.2.RELEASE</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-h2</artifactId>
</dependency>
How can I store a Date using R2DBC? Or if R2DBV support it?
Solution 1:[1]
Instead of Date Use Instant from import java.time.Instant package.
Solution 2:[2]
Use Timestamp.
Example:
CREATE TABLE tweet (id SERIAL PRIMARY KEY, tweet VARCHAR(255), created TIMESTAMP, updated TIMESTAMP );
Repository:
package com.reactive.demo.reactivedemo;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
public interface TweetRepository extends ReactiveCrudRepository<Tweet, Long> {
}
Bean:
package com.reactive.demo.reactivedemo;
import org.springframework.data.annotation.Id;
import java.time.Instant;
public class Tweet {
@Id
private Long id;
public Tweet(Long id, Instant created, Instant updated, String tweet) {
this.id = id;
this.created = created;
this.updated = updated;
this.tweet = tweet;
}
public Tweet() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Instant getCreated() {
return created;
}
public void setCreated(Instant created) {
this.created = created;
}
public Instant getUpdated() {
return updated;
}
public void setUpdated(Instant updated) {
this.updated = updated;
}
public String getTweet() {
return tweet;
}
@Override
public String toString() {
return "Tweet{" +
"id=" + id +
", created=" + created +
", updated=" + updated +
", tweet='" + tweet + '\'' +
'}';
}
public void setTweet(String tweet) {
this.tweet = tweet;
}
private Instant created;
private Instant updated;
private String tweet;
}
Testting code
@Bean
public CommandLineRunner demo(TweetRepository tweetRepo){
return (args) -> {
Flux<Tweet> tweetFlux = Flux.just(new Tweet(null, Instant.ofEpochMilli(System.currentTimeMillis()),Instant.ofEpochMilli(System.currentTimeMillis()), "HEllo")).flatMap(tweetRepo::save);
tweetFlux.thenMany((tweetRepo.findAll())).subscribe(System.out::println);
};
}
Solution 3:[3]
please make sure to use LocalDateTime
in java 8,
The error will go away.
https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html
According to your code,
@Column
private final LocalDateTime validUntil;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | sairam |
Solution 2 | Amit Meena |
Solution 3 | Mafei |