In our Spring project I want to convert Java repository to Kotlin. Repository is an interface with methods and annotations which contains database query as a argument. There are several methods, but the most complex and longest part of the query is repeated. In Java, we inserted a string into the query as a variable.
Current solution in Kotlin cannot compile because 'an annotation argument must be a compile-time constant'.
What is the best way to handle this?
interface PlaceRepository : JpaRepository<Place, UUID>, JpaSpecificationExecutor<Place> {
val HAVERSINE_FORMULA: String
get() =
"""
(6371 * acos(cos(radians(CAST(CAST(:latitude AS string) AS double)))
* cos(radians(p.gpsLatitude)) * cos(radians(p.gpsLongitude) - radians(CAST(CAST(:longitude AS string) AS double)))
sin(radians(CAST(CAST(:latitude AS string) AS double))) * sin(radians(p.gpsLatitude))))
"""
@Query("""
SELECT p AS place,
$HAVERSINE_FORMULA AS distance
FROM Place p
WHERE p.code = :code
""")
fun findByCode(
code: String,
latitude: Double,
longitude: Double
): Optional<PlaceWithDistanceDTO>
}
Thank you
CodePudding user response:
You can try using a companion object as follows:
interface PlaceRepository : JpaRepository<Place, UUID>, JpaSpecificationExecutor<Place> {
companion object {
private const val HAVERSINE_FORMULA =
"""
(6371 * acos(cos(radians(CAST(CAST(:latitude AS string) AS double)))
* cos(radians(p.gpsLatitude)) * cos(radians(p.gpsLongitude) - radians(CAST(CAST(:longitude AS string) AS double)))
sin(radians(CAST(CAST(:latitude AS string) AS double))) * sin(radians(p.gpsLatitude))))
"""
}
@Query("""
SELECT p AS place,
$HAVERSINE_FORMULA AS distance
FROM Place p
WHERE p.code = :code
""")
fun findByCode(
code: String,
latitude: Double,
longitude: Double
): Optional<PlaceWithDistanceDTO>
}