Spring Boot使用@Query获取PostGIS Geometry数据报错求助
解决Spring Data JPA原生查询Geometry列时的No Dialect mapping for JDBC type: 1111错误
问题原因
用原生SQL直接查询coordinates列时,Hibernate的PostGIS方言无法自动将JDBC返回的空间类型(对应JDBC类型码1111,即OTHER)映射为JTS的Geometry对象。而调用findAll()查询整个实体时,Hibernate会通过实体类中Geometry属性的映射配置完成类型转换,因此可以正常运行。
解决方案
方案1:改用JPQL查询(推荐)
放弃原生SQL,使用JPQL查询实体的point属性,让Hibernate自动处理类型映射:
@Repository public interface LocationRepository extends JpaRepository<Location, Long> { Optional<Location> findByPoint(Geometry point); // 替换原生查询为JPQL @Query("SELECT l.point FROM Location l") List<Geometry> findAllPoints(); }
方案2:原生查询中显式转换并自定义类型处理
如果必须使用原生SQL,可通过PostGIS函数将空间类型转换为Hibernate可识别的格式,再手动转换为Geometry:
- 修改Repository的查询语句:
@Query(value = "SELECT ST_AsEWKB(coordinates) FROM locations", nativeQuery = true) List<byte[]> findAllPointsAsEWKB();
- 在业务代码中将二进制数据转换为
Geometry:
import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.io.WKBReader; import java.util.stream.Collectors; // 转换示例 WKBReader reader = new WKBReader(); List<Geometry> geometries = locationRepository.findAllPointsAsEWKB() .stream() .map(wkb -> { try { return reader.read(wkb); } catch (Exception e) { throw new RuntimeException("转换WKB到Geometry失败", e); } }) .collect(Collectors.toList());
方案3:使用@SqlResultSetMapping定义类型映射
通过@SqlResultSetMapping明确指定JDBC类型到实体类型的映射规则:
- 在实体类上添加映射定义:
@Entity @Table(name="locations") @SqlResultSetMapping( name = "GeometryMapping", columns = @ColumnResult(name = "coordinates", type = Geometry.class) ) public class Location { // 原有实体代码... }
- 修改Repository的查询,指定使用该映射:
@Query(value = "SELECT coordinates FROM locations", nativeQuery = true, resultSetMapping = "GeometryMapping") List<Geometry> findAllPoints();
验证测试
修改后重新运行testFindAllPoints()测试,即可正常获取Geometry列表。
内容的提问来源于stack exchange,提问作者mhmuftee
相关产品推荐
相关产品推荐

