Spring Boot - Entity With Kotlin List<Enum> Not Booting - spring

I have been helping my team upgrade our Maven/SpringBoot/Kotlin project from Spring-Boot 2.7.5 to Spring-Boot 3.0.0. However, an issue on startup is preventing us from progressing. This has not been an issue before Spring-Boot 3.0.0.
Upon booting the application, I receive the following stack trace:
org.springframework.context.ApplicationContextException: Unable to start web server
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaSharedEM_entityManagerFactory': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: class sun.reflect.generics.reflectiveObjects.WildcardTypeImpl cannot be cast to class java.lang.reflect.ParameterizedType (sun.reflect.generics.reflectiveObjects.WildcardTypeImpl and java.lang.reflect.ParameterizedType are in module java.base of loader 'bootstrap')
After spending a day checking configurations and isolating the problem, we were left with one entity in our application, where we were still having the issue. We then started removing fields from the entity, until the application was able to run. The field we removed was a kotlin.collections.List of type Interaction, an enum class that we had defined for the application.
In order to ensure privacy, here is an isolated slice of the application MVC that will replicate this issue:
package com.example.adminapp.adminauth.persistence
import com.fasterxml.jackson.databind.ObjectMapper
import jakarta.persistence.*
import org.springframework.data.repository.CrudRepository
import org.springframework.stereotype.Repository
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
#Entity
#Table(name = "a_test_entity")
class AdminTestEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Int? = null
var name: String? = null
#Column
#Convert(converter = StrListConverter::class)
var interactions: List<Interaction> = emptyList()
}
enum class Interaction { HI, BYE }
class StrListConverter : AttributeConverter<List<Interaction>, String?> {
override fun convertToDatabaseColumn(p0: List<Interaction>): String? = ObjectMapper().writeValueAsString(p0)
override fun convertToEntityAttribute(p0: String?): List<Interaction> =
p0?.let { listOf(*ObjectMapper().readValue(it, Array<Interaction>::class.java)) } ?: emptyList()
}
#Repository
interface AdminTestEntityRepository : CrudRepository<AdminTestEntity, Int?>
#RestController
#RequestMapping("/api/v1/admin/test")
class AdminTestController(private val adminTestEntityRepository: AdminTestEntityRepository) {
#GetMapping("all")
fun getAllTest() = adminTestEntityRepository.findAll()
}
The kicker for this whole issue is that it only seems to be List<Enum> that causes this issue. For example, the following three re-definitions do not cause an instance of this issue:
var interactions: ArrayList<Interaction> = emptyList()
var interactions: List<String> = emptyList()
var interactions: List<DataClass> = emptyList()
What could be the cause of this? Why is it only List<Enum>?

It seems that https://hibernate.atlassian.net/browse/HHH-15624 fixed this issue.

Related

UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.NotBlank' validating type java.lang.String

I have #Configuration class in lib.
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
#Configuration
#ConfigurationProperties(prefix = "token")
#Getter
#Setter
#Validated
public class JwtTokenSettings {
#NotBlank
private String jwtSecret;
#NotNull
private Long lifetimeMinutes;
#NotNull
private Long refreshTokenLifetimeMinutes;
}
and imported sbs-validation in my build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
... other dependencies
}
my test application.yml
token:
jwt-secret: test
lifetime-minutes: 1
refresh-token-lifetime-minutes: 1
When i running test to load full context it fails with
Caused by: javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.NotBlank' validating type 'java.lang.String'. Check configuration for 'jwtSecret'
Why its happen? Another service with that config pass context load test and validators do its work
in another app with this config:
token:
jwt-secret:
lifetime-minutes: 1
refresh-token-lifetime-minutes: 1
result is:
Description:
Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'token' to security.jwt.JwtTokenSettings$$EnhancerBySpringCGLIB$$c4509846 failed:
Property: token.jwtSecret
Value:
Origin: class path resource [application.yml]:40:14
Reason: must not be blank
Action:
Update your application's configuration
and when i full jwt-secret property test pass

Getting bean creation errors when creating a shared interface for my ReactiveCrudRepositories, is it possible to create share interfaces like this?

so my Kotlin / spring-boot application makes use of several reactiveCrudRepositories, and I am trying to reduce the amount of code I need to write methods that are common to each table in my database.
I was trying to create a common interface that each table implements, but am getting the following error when i build:
Error creating bean with name 'sharedRepo' defined in com...sharedRepo defined in #EnableR2dbcRepositories declared on R2dbcRepositoriesAutoConfiguireRegistrar.EnableR2dbcRepositoriesConfiguration: Invocation of ini method failed; nested exception is in org.springframework.data.mapping.MappingException: Couldn't find persistentEntity for type class java.lang.Object!
I have tried reducing the complexity of the interface down to just an empty interface (so that i can still write generic methods) but this has not worked.. the following is what my code currently looks like:
itemA.kt
#Table(table_a)
data class itemA(
#Id
#Column("id")
val menuId: UUID
#Column("name")
val prodName: String
...
}
interface AClassRepository : sharedRepo<itemA>, Serializable
itemB.kt
#Table(table_b)
data class itemB(
#Id
#Column("id")
val menuId: UUID
#Column("name")
val prodName: String
...
}
interface BClassRepository : sharedRepo<itemB>, Serializable
SharedRepo.kt
interface sharedRepo<T> : ReactiveCrudRepository<T, UUID>
databaseAssistant.kt
fun <T> sharedRepo<T>.persist(item: T) = {
Try {
//this is calling the ReactiveCrudRepository.save method
save
} ...
}
fun <T> sharedRepo<T>.someOtherDbCall(item: T, newName: String) =
*some other method body*
serviceC.kt
#Service
class ServiceC(
private val repositoryA: AClassRepository,
private val repositoryB: BClassRepository
( {
fun useRepo() =
repositoryB.persist(someInstanceOfItemA)
fun useOtherRepo() =
repositoryA.someOtherDbCall(someInstanceOfItemB, "aNiceName")
}

Spring boot Data JDBC + Querydsl error " Reason: No property count found for type"

I'm trying to use Spring data JDBC with Query DSL in Kotlin.
This is my repository
#Repository
interface UserRepository : PagingAndSortingRepository<User, Int>, QuerydslPredicateExecutor<User> {}
My entity is a simple data object
#Entity
#Table(name = "user")
data class User(
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_seq")
#SequenceGenerator(name = "user_id_seq", sequenceName = "user_id_seq", allocationSize = 1)
val id: Int? = null,
val name: String,
val surname: String)
I've added these lines to my build.gradle
implementation("com.querydsl:querydsl-sql-spring:4.4.0") {
exclude group: 'joda-time', module: 'joda-time'
}
kapt "com.querydsl:querydsl-apt:4.4.0:jpa"
I've added the #EnableJdbcrepositories annotation in my Spring application
But when I try to start my application I get this error:
Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository' defined in my.tests.querydsl.repositories.UserRepository defined in #EnableJdbcRepositories declared on
JdbcRepositoriesRegistrar.EnableJdbcRepositoriesConfiguration: Invocation of init method failed; nested exception is org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract long org.springframework.data.querydsl.QuerydslPredicateExecutor.count(com.querydsl.core.types.Predicate)! Reason: No property count found for type User!
I tried also to remove #EnableJdbcrepositories annotation but the error persists.
What I'm doing wrong? I'm missing some dependency?
Thanks
Infobip Spring Data Querydsl provides QuerydslPredicateExecutor fragment support for Spring Data JDBC (among other things).
With it, UserRepository definition should work as is defined, check out the module README.md JDBC section for details.
If you need SQLQuery, SQLUpdateClause or delete with Predicate support don't miss the QuerydslJdbcFragment.
The Spring-Data book says that only Spring Data JPA and MongoDB support QuerydslPredicateExecutor

Jpa Repository got error cannot not serializable when get data from database

I have a problem when try to get data using JPA Repository,
every time i try to get data always get error java.lang.ClassCastException: shurl.model.Shurl cannot be cast to java.io.Serializable,
i have tried to explorer the solution, but until now still not found any clue to solve this problem
here my error :
2019-04-03 07:36:17.434 ERROR 19348 --- [nio-5001-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: shurl.model.Shurl cannot be cast to java.io.Serializable] with root cause
java.lang.ClassCastException: shurl.model.Shurl cannot be cast to java.io.Serializable
and here my code at jpa repository
package shurl.repository
import shurl.model.Shurl
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.stereotype.Repository
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Page
import java.time.LocalDate
import java.time.LocalDateTime
import shurl.model.ShurlHistory
#Repository
interface ShurlHistoryRepository : JpaRepository<ShurlHistory, String> {
#Query("select b.* from shurl a " +
"left join shurl_history b on b.shurl_code = a.shurl_code " +
"where a.shurl_code = :code",nativeQuery = true )
fun findShurlHistory(code:String):List<ShurlHistory>?
}
and here my model
package shurl.model
import com.fasterxml.jackson.annotation.JsonIgnore
import javax.persistence.*
import org.apache.poi.hpsf.Decimal
import java.time.LocalDate
import java.sql.Blob
import org.hibernate.type.BlobType
import java.time.LocalDateTime
#Entity
#Table(name = "shurl_history", schema = "dbo")
data class ShurlHistory (
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = true)
var id:Long?=null,
#Column(name = "create_date", nullable = false )
var createDate:LocalDateTime = LocalDateTime.now(),
#ManyToOne
#JoinColumn(name = "shurl_code", referencedColumnName = "shurl_code", nullable = true)
var shurl : Shurl? = null
)
can someone help me?
If you reference another object using non-primary key column, make the referenced object serializable.
It's a known bug reported in 2012 and still unsolved.
Make Shurl serialzable and it should work:
#Entity
public class Shurl implements Serializable {
private static final long serialVersionUID = 1L;
}
i think i have found the solution without serializable, i remove id properties in class shurl and i set shurl_code as primary key..

Method signature not resolving for kotlin in Java

IN my project I am using graphql-spring-java to implement a graphql endpoint. I have the graphql schema defined and all the entities put together in kotlin. The problem is that one of my method signatures in my kotlin is not resolving correctly while all the other ones do. Here's the error verbatim:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.coxautodev.graphql.tools.SchemaParser]: Factory method 'schemaParser' threw exception; nested exception is com.coxautodev.graphql.tools.FieldResolverError: No method or field found with any of the following signatures (with or without one of [interface graphql.schema.DataFetchingEnvironment] as the last argument), in priority order:
ninja.familyhomestay.domain.Host.reservations()
ninja.familyhomestay.domain.Host.getReservations()
ninja.familyhomestay.domain.Host.reservations
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:582)
... 105 common frames omitted
Caused by: com.coxautodev.graphql.tools.FieldResolverError: No method or field found with any of the following signatures (with or without one of [interface graphql.schema.DataFetchingEnvironment] as the last argument), in priority order:
ninja.familyhomestay.domain.Host.reservations()
ninja.familyhomestay.domain.Host.getReservations()
ninja.familyhomestay.domain.Host.reservations
at com.coxautodev.graphql.tools.FieldResolverScanner.missingFieldResolver(FieldResolverScanner.kt:51)
at com.coxautodev.graphql.tools.FieldResolverScanner.findFieldResolver(FieldResolverScanner.kt:42)
and here is the code in question:
#Entity
#Table(name = "host")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Document(indexName = "host")
class Host(
...
#OneToMany(mappedBy = "host")
var reservations: MutableSet<Reservation> = HashSet()
) : Serializable
#Entity
#Table(name = "reservation")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Document(indexName = "reservation")
data class Reservation(
....
#ManyToOne
#JoinColumn(name = "host_id")
var host: Host? = null,
...) : Serializable {
companion object {
private const val serialVersionUID = 1L
}
}
Obviously there's nothing wrong with code so I am thinking that it's an issue with kotlin. What do you think? I am using kotlin version 1.2.51 and idea 2018.2.eap.

Resources