I tried to use spatial API in Spring boot.
I tested following SQL query it works fine, so the problem not in database
SELECT
s.ID,
s.LOCATION
FROM PORTS s
where SDO_WITHIN_DISTANCE(
s.LOCATION,
SDO_GEOMETRY(2001, 8307,
SDO_POINT_TYPE( 24.817768,46.599417, NULL),NULL, NULL
),
'distance=10 unit=KM'
) = 'TRUE';
My Entity:
@Entity
@Table(name = "ports")
@Getter @Setter
@NoArgsConstructor
public class JpaPort {
@Id
@Column(name = "id", unique = true, nullable = false, insertable = false, updatable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "location",columnDefinition="SDO_GEOMETRY")
private Geometry location;
private String name;
}
My repository query:
portRepository.findAll(filterWithinRadius(portDTO.getLat(), portDTO.getLon(), portDTO.getRangeInMeters()));
Specification for this:
public static Specification<JpaPort> filterWithinRadius(double latitude, double longitude, double radius) {
return new Specification<JpaPort>() {
@Override
public Predicate toPredicate(Root<JpaPort> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
GeometryFactory factory = new GeometryFactory();
Geometry comparisonPoint = factory.createPoint(new Coordinate(latitude,longitude));
comparisonPoint.setSRID(8307);
Expression<Geometry> dbPoint = root.get("location").as(Geometry.class);
Expression<Boolean> expression = builder.function("SDO_WITHIN_DISTANCE", boolean.class,
dbPoint, builder.literal(comparisonPoint),builder.literal("DISTANCE=1 UNIT=MILE"));
return builder.equal(expression, true);
}
};
}
If I'm using Hibernate I got following error
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
oracle.jdbc.OracleDatabaseException: ORA-01722: invalid number
I don't know my this approach is correct/wrong, because I'm new to spring development, if you have any other solution feel free to answer or comment.
Is there any other way to make the Spatial API query in Hibernate?
My source code - https://drive.google.com/file/d/1loSLFg3Cok9iwtv3apXP3f59QiJdI2eS/view?usp=sharing
You have to compare the result against the varchar 'TRUE'
, just like in your SQL example. Use this:
Expression<String> expression = builder.function("SDO_WITHIN_DISTANCE", String.class,
dbPoint, builder.literal(comparisonPoint),builder.literal("DISTANCE=1 UNIT=MILE"));
return builder.equal(expression, "TRUE");
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.