为啥在尝试将 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_position 和 Point 作为数据类型。
在发布的示例中使用 @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 多对多映射时遇到此错误?
Tapestry 5.3.8 + Jetty + Hibernate 4.3.5 + XAMPP 1.8.3 - IdClass 使用(派生)实体,为啥在尝试合并时它们会分离?