Search code examples
mysqlhibernategeospatialmysql-5.6hibernate-spatial

How to change Geometry object Datatype from polygon object datatype in HibernateSpatial API?


Trying to store Polygon shape in database with HibernateSpatial API. I have followed this tutorial to store values. I am using Mysql as my database server. So Made some couple of changes for my scenario. Getting the following ERROR to store it in the database.

::ERROR::

ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-/192.168.5.244:8080-1) Data truncation: Cannot get geometry object from data you send to the GEOMETRY field

ERROR [com.service.HibernateSaveService] (http-/192.168.5.244:8080-1) Exception :_: could not execute statement

HINT

I am getting this error, Because trying to pass the Polygon directly in the Geometry datatype( It is my assumption). Please help me to fix this issue and help me to store values in database.

My code is below.

ENTITY CLASS :_:

package com.entity;

// Generated Mar 1, 2014 12:22:56 PM by Hibernate Tools 3.4.0.CR1

import static javax.persistence.GenerationType.IDENTITY;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import org.hibernate.annotations.Type;

import com.vividsolutions.jts.geom.Polygon;

/**
 * HibernateSpatial generated by hbm2java
 */
@Entity
@Table(name = "HIBERNATE_SPATIAL", catalog = "geocodedb", uniqueConstraints = @UniqueConstraint(columnNames = "GEO_REGION_NAME"))
public class HibernateSpatialEntity implements java.io.Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Integer prdGeoRegionId;
    private String geoRegionName;
    private String geoRegionDescription;

    @Type(type="org.hibernate.spatial.GeometryType")
    private Polygon geoRegionDefinition;

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "PRD_GEO_REGION_ID", unique = true, nullable = false)
    public Integer getPrdGeoRegionId() {
        return this.prdGeoRegionId;
    }

    public void setPrdGeoRegionId(Integer prdGeoRegionId) {
        this.prdGeoRegionId = prdGeoRegionId;
    }

    @Column(name = "GEO_REGION_NAME", unique = true, nullable = false, length = 50)
    public String getGeoRegionName() {
        return this.geoRegionName;
    }

    public void setGeoRegionName(String geoRegionName) {
        this.geoRegionName = geoRegionName;
    }

    @Column(name = "GEO_REGION_DESCRIPTION", length = 70)
    public String getGeoRegionDescription() {
        return this.geoRegionDescription;
    }

    public void setGeoRegionDescription(String geoRegionDescription) {
        this.geoRegionDescription = geoRegionDescription;
    }

    @Column(name = "GEO_REGION_DEFINITION")
    public Polygon getGeoRegionDefinition() {
        return this.geoRegionDefinition;
    }

    public void setGeoRegionDefinition(Polygon geoRegionDefinition) {
        this.geoRegionDefinition = geoRegionDefinition;
    }

}

PERSIST CLASS :_:

package com.service;

import java.util.Random;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.solartis.entity.HibernateSpatialEntity;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
@Path("/")
public class HibernateSaveService {
    /**
     * mLogger - attribute used for to write the log
     */
    private static final Logger mLogger = LoggerFactory
            .getLogger(HibernateSaveService.class);

    @POST
    @Path("/saveHibernate")
    @Consumes("*/*")
    @Produces("*/*")
    public String saveShapes(String jsonRequest) {
        String statusResult =   null;
        String methodName = "saveShapes";
        StringBuilder regionName    =   null;
        Session session =   null;
        Random random   =   null;
        HibernateSpatialEntity hibernateEntity  =   null;
        Polygon poly    =   null;
        String singleShape  =   "Polygon((-50.123456789 -50.123456789,50.98765432175 -50.753951654852,50 50,-50 50,-50.123456789 -50.123456789))";

        mLogger.debug("Entered inside the Method :_: " + methodName );
        Geometry geom   =   wktToGeometry(singleShape);
        try {
            EntityManager entity = Persistence.createEntityManagerFactory(
                    "spatialPersistenceUnit").createEntityManager();
            session = (Session) entity.getDelegate();
            if (!geom.getGeometryType().equals("Polygon")) {
                throw new RuntimeException("Geometry must be a Polygon. Got a " + geom.getGeometryType());
            }
            else {
                //poly.
                mLogger.info("GeoType :_: " + geom.getGeometryType());
                hibernateEntity =   new HibernateSpatialEntity();
                random  =   new Random();
                hibernateEntity.setGeoRegionDefinition((Polygon)geom);
                hibernateEntity.setGeoRegionDescription("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
                regionName  =   new StringBuilder();
                regionName.append("RegionName :_: ").append(random.nextInt(10000));
                hibernateEntity.setGeoRegionName(regionName.toString());
                mLogger.info("StoredName :_: " + regionName.toString());
                session.beginTransaction();
                session.save(hibernateEntity);
            }

        } catch(Exception exception) {
            mLogger.error("Exception :_: " + exception.getMessage());
        } finally {
            session.clear();
            if ((session != null) && (session.isOpen())) {
                session.close();
            }
        }
        mLogger.debug("Exited from the Method :_: " + methodName);
        return statusResult;
    }

    private Geometry wktToGeometry(String wktPoint) {
        WKTReader fromText = new WKTReader();
        Geometry geom = null;
        try {
            geom = fromText.read(wktPoint);
        } catch (ParseException e) {
            throw new RuntimeException("Not a WKT string:" + wktPoint);
        }
        return geom;
    }
}

DATABASE SCHEMA

+------------------------+--------------+------+-----+---------+----------------+
| Field                  | Type         | Null | Key | Default | Extra          |
+------------------------+--------------+------+-----+---------+----------------+
| PRD_GEO_REGION_ID      | int(11)      | NO   | PRI | NULL    | auto_increment |
| OWNER_ID               | decimal(3,0) | NO   |     | NULL    |                |
| GEO_REGION_NAME        | varchar(50)  | NO   | UNI | NULL    |                |
| GEO_REGION_DESCRIPTION | varchar(70)  | YES  |     | NULL    |                |
| GEO_REGION_DEFINITION  | geometry     | YES  |     | NULL    |                |
+------------------------+--------------+------+-----+---------+----------------+

Regards, ArunRaj.


Solution

  • Solved the Issue by putting the annotation in the proper place.

    ISSUE :_:

    @Type(type="org.hibernate.spatial.GeometryType")
    private Polygon geoRegionDefinition;
    

    I have specified the Type annotation in the wrong place. That is the problem. That is why JavaObject can not transfer the data into a GeometryType.

    Solution :_:

    Just put the Type annotation in the getter method of the Entity Class. The problem has been fixed.

    @Type(type="org.hibernate.spatial.GeometryType")
    @Column(name = "GEO_REGION_DEFINITION")
    public Polygon getGeoRegionDefinition() {
        return this.geoRegionDefinition;
    }
    
    public void setGeoRegionDefinition(Polygon geoRegionDefinition) {
        this.geoRegionDefinition = geoRegionDefinition;
    }