嵌入在Spring Boot中的Geoserver和hibernate / jpa冲突

克鲁申斯坦:

我正在尝试使用Spring Boot Web创建一个需要geoserver保留GeoJSON图层的Web应用程序。

我成功在与spring-boot应用程序相同的tomcat中启动了geoserver。但是,当GeoServer尝试访问postgresql / postgis数据库时会出现问题。Geoserver说:

Error occurred getting featuresUnable to obtain connection: Cannot create PoolableConnectionFactory

由于:

java.lang.ClassCastException: class org.postgis.PGbox2d
at java.lang.Class.asSubclass(Class.java:3404) ~[na:1.8.0_151]
at org.postgresql.jdbc.PgConnection.initObjectTypes(PgConnection.java:645) ~[postgresql-42.1.1.jar:42.1.1]
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:296) ~[postgresql-42.1.1.jar:42.1.1]
at org.postgresql.Driver.makeConnection(Driver.java:450) ~[postgresql-42.1.1.jar:42.1.1]
at org.postgresql.Driver.connect(Driver.java:252) ~[postgresql-42.1.1.jar:42.1.1]
...

我可以通过spring应用程序访问存储在postgresql / postgis中的数据。

这是我的pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
    <relativePath/>
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>

    <dependency>
        <groupId>net.postgis</groupId>
        <artifactId>postgis-jdbc</artifactId>
        <version>2.2.0</version>
        <exclusions>
            <exclusion>
                <groupId>org.postgresql</groupId>
                <artifactId>postgresql</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-spatial</artifactId>
        <version>5.2.12.Final</version>
    </dependency>
    <dependency>
        <groupId>com.bedatadriven</groupId>
        <artifactId>jackson-datatype-jts</artifactId>
        <version>2.2</version>
    </dependency>

    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <version>9.0.2</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

还有应用程序:

package fr.app;

import fr.app.dao.GreffeRepository;
import fr.app.util.TomcatDeployer;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;

import java.util.logging.Logger;

@SpringBootApplication
public class GroLocApplication
{
    private static final Logger LOGGER = Logger.getLogger(GroLocApplication.class.getName());

    public static void main(String... args)
    {
        SpringApplication.run(GroLocApplication.class, args);
    }

    @Bean
    public EmbeddedServletContainerFactory servletContainerFactory()
    {
        return new TomcatDeployer();
    }
}

TomcatDeployer,用于在资源的war文件夹中部署war:

package fr.app.util;

import org.apache.catalina.Context;
import org.apache.catalina.loader.WebappLoader;
import org.apache.catalina.startup.Tomcat;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;

import javax.servlet.ServletException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.logging.Logger;

final public class TomcatDeployer extends TomcatEmbeddedServletContainerFactory
{
    private static final Logger LOGGER = Logger.getLogger(TomcatDeployer.class.getName());
    private static final String WAR_TO_DEPLOY = "war/geoserver.war";

    private String copyResourceToTmp() throws IllegalStateException
    {
        try (InputStream resourceStream = getClass().getClassLoader().getResourceAsStream(WAR_TO_DEPLOY))
        {
            File tmpWar = File.createTempFile("geoserver", ".war");
            Files.copy(resourceStream, tmpWar.toPath(), StandardCopyOption.REPLACE_EXISTING);
            return tmpWar.getAbsolutePath();
        }
        catch (IOException e)
        {
            throw new IllegalStateException("Cannot copy geoserver.war resource", e);
        }
    }

    @Override
    protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat)
            throws IllegalStateException
    {
        if (!new File(tomcat.getServer().getCatalinaBase(), "webapps").mkdirs())
        {
            throw new IllegalStateException("Cannot create a webapps directory on tomcat");
        }

        try
        {
            final String pathToWar = copyResourceToTmp();
            LOGGER.info(pathToWar);
            final Context context = tomcat.addWebapp("/geoserver", pathToWar);
            final WebappLoader loader = new WebappLoader(Thread.currentThread().getContextClassLoader());
            context.setLoader(loader);
        }
        catch (ServletException e)
        {
            throw new IllegalStateException("Failed to add geoserver", e);
        }
        return super.getTomcatEmbeddedServletContainer(tomcat);
    }
}

格雷夫实体:

package fr.app.entity;

import com.bedatadriven.jackson.datatype.jts.serialization.GeometryDeserializer;
import com.bedatadriven.jackson.datatype.jts.serialization.GeometrySerializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.vividsolutions.jts.geom.Geometry;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Greffe
{
    @Id
    private String id;

    @JsonSerialize(using = GeometrySerializer.class)
    @JsonDeserialize(using = GeometryDeserializer.class)
    private Geometry coord;
    // getters...
}

而dao是经典的CrudRepository<Greffe,String>延伸。

那么是否可以将GeoServer真正嵌入到与Spring Boot应用程序的tomcat相同的tomcat中?(可能是因为我这样做了,但这真的是个好主意吗?)

如果是这样,我该如何避免这种麻烦?

在此先感谢:)

bkiselka:

我不会将GeoServer嵌入到您的应用程序正在使用的同一个Tomcat中。是的,有可能,是的;但不是一个好主意。推理:在Tomcat启动期间,GeoServer和您的应用程序尚未运行(尚未运行)-但是,如果您的应用程序在启动期间需要GeoServer,则它必须失败。解决方案:将GeoServer放在可启动应用程序之前启动的serparat Tomcat中。

麻烦您(和ClassCastException):确保使用彼此匹配的postgres和postgis驱动程序版本以及您使用的数据库版本。您收到的错误似乎与https://github.com/brettwooldridge/HikariCP/issues/1476有关-也许那里的信息可以为您提供帮助。

我个人从未听说过com.bedatadriven.jackson.datatype.jts-确保该库的相关JTS版本与您的GeoServer中使用的版本匹配。

在使用HibernateSpatial时,请确保正确配置HibernateSpatial。我没有看到配置。也许将hibernate-spatial用于postgis是一种解决方案:

<groupId>org.hibernatespatial</groupId>
<artifactId>hibernate-spatial-postgis</artifactId>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

用于Spring Boot的嵌入式Redis

当使用spring-boot和spring-data-jpa加载时,Hibernate无法加载JPA 2.1 Converter

在JPA 2.0中捕获约束冲突

Spring Data JPA和Hibernate

Spring Data JPA通过嵌入式密钥中的多个字段查找

如何使用spring-boot,spring-data-jpa和hibernate获得“无级联”的行为?

如何在Spring JPA中访问嵌入式类的字段

在Spring Data JPA中嵌入对象而不是链接

使用嵌入式模型的Spring Boot Hibernate ManyToMany Relation

Spring Boot嵌入式tomcat日志

Spring Boot数据嵌入式Cassandra

Spring Boot嵌入式Tomcat性能

Spring Boot + GWT嵌入式配置

Spring Boot 1.4.1和WAS 9冲突

在Spring Boot / Hibernate / JPA中为联接表指定表和字段名称

Spring Boot和Spring Data JPA中的事务管理

Azure DocumentDB和Spring Boot冲突

在Spring Boot JPA中映射枚举和时间类型

如何禁用嵌入式数据库Spring-boot spring-data-jpa

Grails 2.4.4中的Hibernate JPA冲突

在Hibernate / JPA中检查多个子约束冲突

使用可嵌入键中的两个字段进行删除的 Spring Data JPA 方法

Spring Boot JPA Hibernate CRUD 存储库中的查找表

如何在 Spring Boot 中捕获 hibernate/jpa 约束违规?

如何使用 Spring Boot 配置 JPA + HIBERNATE

在 spring boot jpa 存储库中保留嵌入(相关)项目?

Spring Data JPA 接口和基于类的投影不适用于嵌入式键的 DISTINCT 字段

BeanDefinitionOverrideException,Spring Data JPA 和 JDBC bean 冲突

实现 Spring JPA 时的方法冲突