Reputation: 35
I started using Hibernate to do queries and I noticed that if I want to use repository to execute queries, that I have to use Entity in the repository to map the value that returned database.
Is there anyway for me to run query in any repository and return the data and map into java class with same name.
Like
@Query(value = "SELECT location_id, (3959 * acos (cos(radians(:lat)) * cos(radians(l.latitude)) * cos(radians(l.longitude) - radians(:lon)) + sin(radians(:lat)) * sin(radians(l.latitude)))) AS distance FROM location l having distance < :mile order by distance limit 0, :limitNum", nativeQuery = true)
List<LocationDistance> searchLocationByRadius(@Param("lat") double lat, @Param("lon") double lon, @Param("mile") double distance, @Param("limitNum") int limit);
So the location_id and distance field returned from Query will be auto map into LocationDistance object.
Upvotes: 0
Views: 781
Reputation: 737
You have 2 options:
@Query(value = "SELECT new example.LocationDistance(location_id, distance_calculation) " +
"FROM location ...")
List<LocationDistance> searchLocationByRadius(@Param("lat") double lat, @Param("lon") double lon, @Param("mile") double distance, @Param("limitNum") int limit);
In this approach, you can't use cos/sin/radians functions directly as they are not supported by JPQL. Instead, you need to use JPQL function
to call them, like:
function('cos', tab.column)
Or if you use hibernate, you can register a function with a hibernate dialect.
@SqlResultSetMapping
and @NamedNativeQuery
First, you need to add @SqlResultSetMapping
and @NamedNativeQuery
annotations to your entity class.
@SqlResultSetMapping(
name="myMapping",
classes={
@ConstructorResult(
targetClass=LocationDistance.class,
columns={
@ColumnResult(name="location_id"),
@ColumnResult(name="distance")
}
)
}
)
@NamedNativeQuery(name="Location.searchLocationByRadius",
resultSetMapping="myMapping",
query="...")
@Entity
public class Location {
...
}
Second, you need to add a method to your spring repository interface named exactly as the name of your @NamedNativeQuery
.
@Repository
public interface LocationRepository extends JpaRepository<Location, Long> {
List<LocationDistance> searchLocationByRadius(...);
}
Upvotes: 1