1

I am trying to configure Hibernate Spatial into a Spring Boot project on which I am working and I am finding some problem.

I am using MariaDB (so it is MySql) nd Hibernate was previously corrected configured (I used it for all not GIS functionality without any problem).

I am starting using this tutorial: http://www.hibernatespatial.org/documentation/02-Tutorial/01-tutorial4/

But I am using Hibernate 5 instead Hibernate 4 (I can see that into my External Libraries I have Hibernate 5.0.11) and from what I have understand Hibernate Spatial is nativelly into Hibernate 5.

So, this is my pom.xml content:

<?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>

So, as you can see I have added this dependency:

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

I think that I need it to have the geographical type as Point (but I am absolutly not sure about it).

Then I have this entity class that map a table:

@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

    ...........................................................
    ...........................................................
    ...........................................................
}

In this class I have added this field:

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

that should map the field of the database accomodation table having name geographical_position and Point as data type.

On the posted example uses @Type(type="org.hibernate.spatial.GeometryType") instead the GeolatteGeometryType but in my org.hibernate.spatial.* package I have not the GeometryType but I can find this GeolatteGeometryType class (I think that maybe could be a newer implementation provided by Hibernate 5, but I am not sure about it).

When I start my application I obtain the following error message in the staccktrace:

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

This is also my application.properties configuration file:

#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

What is the problem? What am I missing? How can I solve this issue?

AndreaNobili
  • 40,955
  • 107
  • 324
  • 596
  • Judging from your `application.properties` you are trying very hard to not use the auto configuration features. Next to that use the correct version of `hibernate-spatial` use `${hibernate.version}` instead of defining a version. – M. Deinum Oct 25 '16 at 13:16
  • @M.Deinum what exactly is this "auto configuration features"? – AndreaNobili Oct 25 '16 at 13:18
  • You have things like `db.url`, `hibernate.dialect` those aren't used/utilized by Spring Boot so you must be configuring things manually instead of letting Spring Boot auto configure a `DataSource` and `EntitymanagerFactory`. Regardless of this, I suspect that you are using the wrong version and as mentioned use `${hibernate.version}` in the version field to get the matching version for the hibernate version in use. Use `@Type("geolatte_geometry")` instead of what you have now. – M. Deinum Oct 25 '16 at 13:23
  • @M.Deinum So I have imported the Hibernate Spatial 5.0.11 (the same of the used Hibernate version) but I obtain the same error: Caused by: java.lang.NoSuchMethodException: org.hibernate.spatial.GeolatteGeometryType.() – AndreaNobili Oct 25 '16 at 13:27
  • Read my comment... You shouldn't be using that, use `@Type("geolatte_geometry") `instead of what you have now (as explained in the reference guide). – M. Deinum Oct 25 '16 at 13:28
  • @M.Deinum mmm using Type("geolatte_geometry") instead Type(type="org.hibernate.spatial.GeolatteGeometryType") IntelliJ sign me this error: Error:(49, 11) java: cannot find symbol symbol: method value() location: interface org.hibernate.annotations.Type – AndreaNobili Oct 25 '16 at 13:36
  • My sloppy paste issues (but you can also read the reference guide yourself or used code completion in intellij). `@Type(type="geolatte_geometry")` – M. Deinum Oct 25 '16 at 14:10
  • @M.Deinum Now the IDE don't give me error on the line but I am obtaining this error: "Caused by: java.lang.ClassNotFoundException: Could not load requested class : geolatte_geometry" – AndreaNobili Oct 25 '16 at 14:24
  • Make sure you have correctly set the dialect to the spatial dialect... – M. Deinum Oct 26 '16 at 05:52

2 Answers2

1

Here is simple example(Adding for future references) to use hibernate spatial with Spring-boot.

Add spring-boot-starter-data-jpa, hibernate-spatial and mydql connector maven dependencies.

        <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>

create Entity class.

@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 Impl

@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();
    }

}

Finally application.properties file.

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
Karthik Prasad
  • 9,662
  • 10
  • 64
  • 112
0

You need to configure a SpatialDialect. The generic Dialects don't expose the spatial functions and spatial types. See the documentation at: http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#spatial

Also, you shouldn't need to use any @Type annotation on your class members.

Karel Maesen
  • 751
  • 5
  • 7