为啥在尝试将 Hibernate Spatial 用于 Spring Boot 项目时出现此错误?实例化异常

Posted

技术标签:

【中文标题】为啥在尝试将 Hibernate Spatial 用于 Spring Boot 项目时出现此错误?实例化异常【英文标题】:Why I have this error trying to use Hibernate Spatial into a Spring Boot project? InstantiationException为什么在尝试将 Hibernate Spatial 用于 Spring Boot 项目时出现此错误?实例化异常 【发布时间】:2016-10-25 13:12:09 【问题描述】:

我正在尝试将 Hibernate Spatial 配置到我正在处理的 Spring Boot 项目中,但我发现了一些问题。

我正在使用 MariaDB(所以它是 MySql)并且 Hibernate 之前已更正配置(我将它用于所有非 GIS 功能,没有任何问题)。

我开始使用本教程: http://www.hibernatespatial.org/documentation/02-Tutorial/01-tutorial4/

但我使用的是 Hibernate 5 而不是 Hibernate 4(我可以在我的外部库中看到我有 Hibernate 5.0.11)并且据我了解 Hibernate Spatial原生进入 Hibernate 5

所以,这是我的 pom.xml 内容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>BeTriviusController</groupId>
    <artifactId>BeTriviusController</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <springboot.version>1.4.1.RELEASE</springboot.version>
    </properties>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.4.1.RELEASE</version>
        </parent>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!--dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency-->

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

        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-test</artifactId>
            </dependency>
            <dependency>
                <groupId>org.assertj</groupId>
                <artifactId>assertj-core</artifactId>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>RELEASE</version>
            </dependency>

            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-spatial</artifactId>
                <version>5.0.2.Final</version>
            </dependency>

        </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

所以,如你所见,我添加了这个依赖项:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-spatial</artifactId>
    <version>5.0.2.Final</version>
</dependency>

我认为我需要将地理类型设为 Point(但我完全不确定)。

然后我有这个映射表的实体类:

@Entity
@Table(name = "accomodation")
public class Accomodation implements Serializable 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;
    //private Integer id;

    /*@ManyToOne
    private Users users;
    */

    @OneToMany(mappedBy = "accomodation")
    private List<Room> rooms;

    private String name;

    @Column(name = "description")
    @Type(type="text")
    private String description;

    @Column(name = "geographical_position")
    @Type(type="org.hibernate.spatial.GeolatteGeometryType")
    private Point location;

    ...........................................................
    ...........................................................
    ...........................................................
    CONSTRUCTOR AND GETTER AND SETTER METHODS

    ...........................................................
    ...........................................................
    ...........................................................

在这个类中我添加了这个字段:

@Column(name = "geographical_position")
@Type(type="org.hibernate.spatial.GeolatteGeometryType")
private Point location;

应该映射数据库 accommodation 表的字段,名称为 geographical_positionPoint 作为数据类型。

在发布的示例中使用 @Type(type="org.hibernate.spatial.GeometryType") 而不是 GeolatteGeometryType 但在我的 org.hibernate 中。 spatial.* 包我没有 GeometryType 但我可以找到这个 GeolatteGeometryType 类(我认为这可能是 Hibernate 5 提供的较新的实现,但是我不确定)。

当我启动我的应用程序时,我在堆栈跟踪中收到以下错误消息:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1076) ~[spring-context-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:851) ~[spring-context-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) ~[spring-context-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
    at com.betrivius.Application.main(Application.java:17) [classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_65]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_65]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_65]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_65]
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) [idea_rt.jar:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:954) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:882) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    ... 21 common frames omitted
Caused by: org.hibernate.MappingException: Could not instantiate Type: org.hibernate.spatial.GeolatteGeometryType
    at org.hibernate.type.TypeFactory.type(TypeFactory.java:139) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.type.TypeFactory.byClass(TypeFactory.java:109) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.type.TypeResolver.heuristicType(TypeResolver.java:112) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:416) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:398) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.mapping.Property.isValid(Property.java:225) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:595) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.mapping.RootClass.validate(RootClass.java:265) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:443) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final]
    ... 27 common frames omitted
Caused by: java.lang.InstantiationException: org.hibernate.spatial.GeolatteGeometryType
    at java.lang.Class.newInstance(Class.java:427) ~[na:1.8.0_65]
    at org.hibernate.type.TypeFactory.type(TypeFactory.java:134) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    ... 37 common frames omitted
Caused by: java.lang.NoSuchMethodException: org.hibernate.spatial.GeolatteGeometryType.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_65]
    at java.lang.Class.newInstance(Class.java:412) ~[na:1.8.0_65]
    ... 38 common frames omitted


Process finished with exit code 1

这也是我的 application.properties 配置文件:

#No auth  protected
endpoints.shutdown.sensitive=true
#Enable shutdown endpoint
endpoints.shutdown.enabled=true
logging.file=BeTriviusController.log
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
# Thymeleaf
spring.thymeleaf.cache:false
# Database
db.driver:com.mysql.jdbc.Driver
db.url:jdbc:mysql://MY_DB_IP:3306/MY_DB_NAME
db.username:myusername
db.password:mypassword

# Hibernate
hibernate.dialect:org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql:true
hibernate.hbm2ddl.auto:validate
entitymanager.packagesToScan:com.betrivius.domain
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

有什么问题?我错过了什么?我该如何解决这个问题?

【问题讨论】:

从您的application.properties 来看,您正在努力不使用自动配置功能。旁边使用正确版本的hibernate-spatial 使用$hibernate.version 而不是定义版本。 @M.Deinum 这个“自动配置功能”到底是什么? 你有像 db.url, hibernate.dialect 这样的东西,Spring Boot 没有使用/使用这些东西,所以你必须手动配置,而不是让 Spring Boot 自动配置 DataSource 和 @987654334 @。不管怎样,我怀疑您使用了错误的版本,并且如上所述在版本字段中使用$hibernate.version 来获取正在使用的休眠版本的匹配版本。使用@Type("geolatte_geometry") 而不是你现在拥有的。 @M.Deinum 所以我已经导入了 Hibernate Spatial 5.0.11(与使用的 Hibernate 版本相同)但我得到了同样的错误:Caused by: java.lang.NoSuchMethodException: org.hibernate .spatial.GeolatteGeometryType.() 阅读我的评论...你不应该使用它,使用 @Type("geolatte_geometry") 而不是你现在拥有的(如参考指南中所述)。 【参考方案1】:

这是一个简单的例子(添加以供将来参考)在 Spring-boot 中使用休眠空间。

添加 spring-boot-starter-data-jpa、hibernate-spatial 和 mydql 连接器 maven 依赖项。

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

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-spatial</artifactId>
            <version>$hibernate.version</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

创建实体类。

@Entity
public class KSpatial implements Serializable 

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue
    private int spId;
    private int roadId;
    private Point<G2D> currentPosition;
    //getters and setters


DAO 实现

@Repository
public class KpSpatialDaoImpl implements KpSpatialDao

    @Autowired
    private EntityManagerFactory emf;

    private SessionFactory sf;

    @PostConstruct
    public void init() 
        sf = emf.unwrap(SessionFactory.class);
    

    @Override
    @Transactional
    public boolean add(KpSpatial add) 
        final Session session = sf.getCurrentSession(); 
        session.save(add);
        return true;
    

    @Override
    @Transactional
    public List<KpSpatial> list() 
        final Session session = sf.getCurrentSession(); 
        return session.createQuery("from KpSpatial", KpSpatial.class).getResultList();
    


最后是 application.properties 文件。

spring.datasource.url=jdbc:mysql://localhost:3306/my_spatial
spring.datasource.username=test
spring.datasource.password=test123
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.spatial.dialect.mysql.MySQL56InnoDBSpatialDialect
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext

【讨论】:

【参考方案2】:

您需要配置一个 SpatialDialect。通用方言不公开空间功能和空间类型。参见文档:http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#spatial

此外,您不需要对您的班级成员使用任何 @Type 注释。

【讨论】:

以上是关于为啥在尝试将 Hibernate Spatial 用于 Spring Boot 项目时出现此错误?实例化异常的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate Spatial PostGIS 1.1.1 映射到视图而不是表

休眠空间:找不到功能

为啥我在尝试实现 Hibernate 多对多映射时遇到此错误?

为啥这个 Hibernate MySQL 连接是只读的?

Tapestry 5.3.8 + Jetty + Hibernate 4.3.5 + XAMPP 1.8.3 - IdClass 使用(派生)实体,为啥在尝试合并时它们会分离?

为啥 Hibernate 文档建议将连接表用于一对多关系?