Failed to convert 1985-04-12T23:20 into java.util.Date - spring

[Spring + Kotlin]
These are the dependencies:
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-data-rest")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-web-services")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.4.0")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
This is the Entity:
#Entity
class MatchEntity(
#Id #GeneratedValue val id: Long,
#NotBlank val matchDateTime: Date,
#NotBlank #ManyToOne #JoinColumn val tournamentInvolved: TournamentEntity
)
Whenever I try to run the following query:
interface MatchRepository : JpaRepository<MatchEntity, Long> {
fun findMatchesByMatchDateTimeIsAfter(matchDateTime: Date)
}
with a test string like so 1985-04-12T23:20, I get the error:
QueryMethodParameterConversionException: Failed to convert 1985-04-12T23:20 into java.util.Date!
I tried, as suggested here, with patterns like #DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) and #DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") in the signature of the query method, without solving.
Also, as suggested here, I tried adding
compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.4.0") to the dependencies
spring.jackson.serialization.write_dates_as_timestamps=false to the application.properties.
Didn't work.
UPDATE:
I also tried with LocalDateTime and Instant classes. Still getting the same Exceptions:
QueryMethodParameterConversionException: Failed to convert 1985-04-12T23:20 into java.time.LocalDateTime!
QueryMethodParameterConversionException: Failed to convert 1985-04-12T23:20 into java.time.Instant!

Solved
Using #DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm") worked.

Related

HQL Expects java.time.duration even though method-head and usage suggest LocalDateTime

I am writing a query within a JpaRepository which takes a String and 3 LocalDateTimes as parameters. Within the query I first compare the String like an Id and afterwards I use a different Column of the corresponding Entity to create LocalDateTimes using appropriate operators for Hibernate 6.
The Application starts up normal but when i call the query I get the following Error:
Argument [2023-01-23T11:43:59] of type [java.time.LocalDateTime] did not match parameter type [java.time.Duration (n/a)]
The Argument obviously got parsed correctly by the Restcontroller but Hibernate does not seem to create the query as expected.
The following is the Code for the Repository and the query in question:
public interface ExchangePairRepository extends JpaRepository<MyEntity, Long> {
#Query("SELECT ep.unit FROM MyEntity ep WHERE ep.id= :id AND ((ep.context = 'start' AND ((ep.unit = 'day' AND (:start+ ep.duration day) > :now) "
+ "OR (ep.unit = 'month' AND (:start+ ep.duration month) > :now))) OR (ep.context = 'end' AND ((ep.unit = 'day' AND (:now + ep.duration day) > :end) "
+ "OR (ep.unit = 'month' AND (:now + ep.duration month) > :end)) ))")
List<String> findViable(#Param("matNrOrig") String id, #Param("start") LocalDateTime start, #Param("end") LocalDateTime end,
#Param("now") LocalDateTime now);
}
Below is the Entity which i being used for the query:
#Entity
#Table(name = "my_entity")
#Data
public class MyEntity{
(...)
#Column(name = "id_orig")
private String idOrig;
ยด
#Column(name = "id_target")
private String idTarget;
#Column(name = "context")
private String context;
#Column(name = "duration")
private int duration;
#Column(name = "unit")
private String unit;
}
Is this a bug or am I doing something wrong? Any help is much appreciated.
I am using Hibernate 6.1.6.Final and Spring Boot 3.0.1 with Java 17
Edit:
Casting the parameters within the query solved the problem for now, though it does not look very pretty. I will just wait for the bug being fixed in one of the next releases.
This is a bug in the new parameter type inference logic. I can reproduce with just this query:
session.createQuery("select :dt + 1 day")
.setParameter("dt", LocalDateTime.now())
.getSingleResult();
I have opened an issue for you here: https://hibernate.atlassian.net/browse/HHH-16102
UPDATE
The following workaround is very ugly, but works:
session.createQuery("select cast(:dt as LocalDateTime) + 1 day")
.setParameter("dt", LocalDateTime.now())
.getSingleResult();

How di I turn my class into an Entity in Room Persistence?

This is my first time using Room Persistence Library and I am having difficulties understanding the concept of entity.
So I have these two classes:
public class CapturedTime
{
#SerializedName("startTime")
#Expose
private Long startTime;
#SerializedName("endTime")
#Expose
private Long endTime;}
and
public class CapturedItem implements Parcelable {
private String serialNumber;
private CapturedTime firstCapturedTime;
private CapturedTime secondCapturedTime;}
I believe it's pretty straightforward for the CapturedTime class but I have no idea what I should do for the CapturedItem class. Can I just make the CapturedTime variables into columns or are there steps that I should do first?
First add dependency in buid.gradle file
dependencies {
def room_version = "2.1.0-rc01"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor
}
After that use #Entity annotation to declare normal POJO class as entity in Room persistence library.
#Entity(tableName = "your_table_name")
public class CapturedTime{
#SerializedName("startTime")
#Expose
#ColumnInfo(name = "start_time")
private long startTime;
#SerializedName("endTime")
#Expose
#ColumnInfo(name = "end_time")
private long endTime;
}
#ColumnInfo used to declare column name in table, by default column name is variable name if you do't provide #ColumnInfo annotation
If you want to store custom object in room you use
#TypeConverters() annotation
In your case,
#TypeConverters(CapturedTime.class)
private CapturedTime firstCapturedTime;
For more information please visit this

Spring JPA naming query with orderBy doesn't work

I'm using Spring Boot 2, Spring JPA, Spring Data.
I'm trying to get the first result from a table in which I want to sort results by a int property asc.
This is my bean:
#Entity
public class DatabaseInstance extends AbstractEntity {
#NotNull
#Enumerated(EnumType.STRING)
#Column(nullable = false)
private Supplier supplier;
NotNull
#Column(nullable = false, columnDefinition = "INT DEFAULT 0.0")
private int databaseCount = 0;
and this is my repository:
#Transactional
public interface DatabaseInstanceRepository extends JpaRepository<DatabaseInstance, Long> {
public Optional<DatabaseInstance> findFirstOrderByDatabaseCountAsc();
}
According to Spring manual I can order by property name + asc word. At the same time I want the first result (so i get the instance with the lower databaseCount value).
I get this error:
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property asc found for type int! Traversed path: DatabaseInstance.databaseCount.
I am not able to figure out what's wrong with my method name. Some advice?

spring boot, jackson and localdate

I use spring boot with mysql
in my application.properties
spring.jpa.generate-ddl=true
spring.jackson.serialization.write-dates-as-timestamps=false
In my build.gradle I have
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-data-rest')
compile('org.springframework.boot:spring-boot-starter-web')
compile 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
In my java class
import java.time.LocalDate;
#Entity
public class WebSite implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long webSiteId;
private LocalDate date;
...
}
When this table is created,
date field is created like a TINYBLOB
Why is not a date
This is not an issue with Jackson, but rather that whatever you are using for ORM doesn't know how to convert a Java LocalDate to a MySQL Date.
There are two ways to do this. If you are using Hibernate, you simply include org.hibernate:hibernate-java8 in your dependencies.
Alternatively, if you want just use JPA, you need to create an Attribute Converter. For example:
#Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
#Override
public Date convertToDatabaseColumn(LocalDate locDate) {
return (locDate == null ? null : Date.valueOf(locDate));
}
#Override
public LocalDate convertToEntityAttribute(Date sqlDate) {
return (sqlDate == null ? null : sqlDate.toLocalDate());
}
}
The Attribute Converter will handle converting between a Java LocalDate and MySQL Date.
See: http://www.thoughts-on-java.org/persist-localdate-localdatetime-jpa/

Sonar errors wehn using Lombok #Setter(value = AccessLevel.PRIVATE)

If I use the Lombok #Setting annotation on a field with a value of PRIVATE
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Notification implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Setter(value = AccessLevel.PRIVATE)
private String id;
private long userId;
private Event event;
private long timestamp = System.currentTimeMillis();
public Notification(final String id) {
this.id = id;
}
}
The Sonar Maven plugin gives the following error:
ERROR] Failed to execute goal org.codehaus.mojo:sonar-maven-plugin:2.7.1:sonar (default-cli) on project mio-events: Unable to analyze .class file tv/nativ/mio/event/model/Notification: 0 is not a valid line for a file -> [Help 1]
Changing the #Setting value to public fixes the issue, as does removing #Setting altogether and adding a manual private setter for the field.
Any idea what the issue might be?
Thanks
Nick
Sonar doesn't really support Lombok: Feature request for lombok like tools
Prior to running sonar you should delombok the source and use the generated sources for analysis. Information about this is on the page: Delombok. If you are using maven there's an example of using this technique here: Example Pom

Resources