瞎摸了3+0.5天,终于解决了
应届生新入职,负责Greenplum数据库。之前没有听说过这个,而且需要使用Hibernate-spatial处理Geometry类型,Hibernate与Springboot data JPA我也是没有用过,之前学的是Springboot+Mybatis(plus)已经熟练了,这次JPA对我来说都是全新的东西,而且JPA操作greenplum的空间数据的网上资料很少,没有找到一个好的例子,只能自己走一步看一步。
正确解决方案:application.properties配置换成postgresql的jdbc的driver,url。不能使用Greenplum的jdbc与url
application.properties
#spring.datasource.driver-class-name=com.pivotal.jdbc.GreenplumDriver
spring.datasource.driver-class-name=org.postgresql.Driver
#spring.datasource.url=jdbc:pivotal:greenplum://xxx.xxx.x.xx:????;DatabaseName=bigdata
spring.datasource.url=jdbc:postgresql://xxx.xxx.x.xx:????/bigdata
数据库表
表信息
CREATE TABLE "public"."Untitled" (
"the_geom" "public"."geometry",
"name" varchar(255) COLLATE "pg_catalog"."default",
"id" int4 DEFAULT nextval('city_test_one_id_seq'::regclass)
)
;
参考网上例子写的程序一直报错,看了各种错误解决方案,然后一直尝试不同的解决办法,解决错误,最后正确方案来袭!
1.导入依赖
需要使用最新的版本
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.4.18.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-spatial</artifactId>
<version>5.4.18.Final</version>
</dependency>
最新版本已弃用com.vividsolutions.jts.geom.Geometry
,网上多数博客都是使用的此类型。
需要换成org.geolatte.geom.Geometry类型!
我也不知道要导什么依赖,导了一堆带geolatte的
<dependency>
<groupId>org.geolatte</groupId>
<artifactId>geolatte-geom</artifactId>
<version>1.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.geolatte/geolatte-geojson -->
<dependency>
<groupId>org.geolatte</groupId>
<artifactId>geolatte-geojson</artifactId>
<version>1.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.geolatte/geolatte-common-hibernate -->
<dependency>
<groupId>org.geolatte</groupId>
<artifactId>geolatte-common-hibernate</artifactId>
<version>0.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.geolatte/geolatte-common -->
<dependency>
<groupId>org.geolatte</groupId>
<artifactId>geolatte-common</artifactId>
<version>0.8</version>
</dependency>
配置
application.properties
#通用数据源配置
#spring.datasource.driver-class-name=com.pivotal.jdbc.GreenplumDriver
spring.datasource.driver-class-name=org.postgresql.Driver
#spring.datasource.url=jdbc:pivotal:greenplum://xxx.xxx.x.xx:????;DatabaseName=bigdata
spring.datasource.url=jdbc:postgresql://xxx.xxx.x.xx:????/bigdata
spring.datasource.username=gpadmin
spring.datasource.password=gpadmin
# Hikari 数据源专用配置
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
# JPA 相关配置
spring.jpa.database=postgresql
spring.jpa.database-platform=org.hibernate.spatial.dialect.postgis.PostgisPG9Dialect
#spring.jpa.database-platform=org.hibernate.spatial.dialect.postgis.PostgisDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.open-in-view=true
application.yml
Entity里面@Table(“pulic.city_test_one”),如果不配置这个,JPA默认SQL里面是public_city_test_one,.被转换了,就找不到表格了。所以需要配置naming.PhysicalNamingStrategyStandardImpl
spring:
jpa:
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
2.Entity
自定义的@Convert(converter = WkbConvertToGeometry.class)解决了不能反序列化错误。使用@Convert就不能使用@Type了,报错会提示你这两个只能写其中一个。经里对我说不能使用自定义转换器!此方式不行了,又摸了一上午,解决了
正确解决方案:换postgresql的jdbc的driver,url。不能使用Greenplum的jdbc与url
application.properties
#spring.datasource.driver-class-name=com.pivotal.jdbc.GreenplumDriver
spring.datasource.driver-class-name=org.postgresql.Driver
#spring.datasource.url=jdbc:pivotal:greenplum://xxx.xxx.x.xx:????;DatabaseName=bigdata
spring.datasource.url=jdbc:postgresql://xxx.xxx.x.xx:????/bigdata
在这里插入代码片
import com.kqgeo.greenplum_two.utils.WkbConvertToGeometry;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.geolatte.geom.Point;
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Table(name = "public.city_test_one")
public class CityTest implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="id")
private Integer id;
@Column(name = "the_geom",columnDefinition = "geometry(Point,4326)")
@Convert(converter = WkbConvertToGeometry.class)
private Point the_geom;
@Column(name = "name")
private String name;
}
3.Repository
@Repository
public interface CityDao extends JpaRepository<CityTest,Integer> {
}
4.Converter转换器(此方案被丢弃)
public class WkbConvertToGeometry implements AttributeConverter<Point, String> {
@Override
public String convertToDatabaseColumn(Point geometry) {
ByteBuffer byteBuffer = Wkb.toWkb(geometry);
String s = String.valueOf(byteBuffer);
return s;
}
@Override
public Point convertToEntityAttribute(String wkb) {
ByteBuffer byteBuffer=ByteBuffer.from(wkb);
return (Point)Wkb.fromWkb(byteBuffer);
}
}
5.测试
save()测试 //insert update成功
CityTest c=new CityTest();
c.setId(4);
String pointStr1 = "SRID=4326;POINT(115 35)";
Point decode =(Point) Wkt.newDecoder().decode(pointStr1);
System.out.println(decode.getSRID());
System.out.println(Wkt.toWkt(decode));
if (decode != null) {
c.setThe_geom(decode);
}
c.setName("test");
System.out.println(c.toString());
cityDao.save(c);
查询测试 //selectById成功
/*Optional<CityTest> byId = cityDao.findById(1);
System.out.println(byId.get().toString());*/