21

Is there a way to map Point column to Java entity field?

I tried Hibernate Spatial 4.0, but seems that it doesn't work with pure PostgreSQL without PostGIS. Here is point field definition:

import com.vividsolutions.jts.geom.Point;
...
@Column(columnDefinition = "point")
@Type(type = "org.hibernate.spatial.GeometryType")
private Point location;

Dialect in persistence.xml:

<property name="hibernate.dialect"  value="org.hibernate.spatial.dialect.postgis.PostgisDialect" />

And when I try to persist this entity, exception is thrown:

org.postgresql.util.PSQLException: Unknown type geometry.
at org.postgresql.jdbc2.AbstractJdbc2Statement.setPGobject(AbstractJdbc2Statement.java:1603)
at org.postgresql.jdbc2.AbstractJdbc2Statement.setObject(AbstractJdbc2Statement.java:1795)
at org.postgresql.jdbc3g.AbstractJdbc3gStatement.setObject(AbstractJdbc3gStatement.java:37)
at org.postgresql.jdbc4.AbstractJdbc4Statement.setObject(AbstractJdbc4Statement.java:46)
at org.hibernate.spatial.dialect.AbstractJTSGeometryValueBinder.bind(AbstractJTSGeometryValueBinder.java:48)
at org.hibernate.spatial.dialect.AbstractJTSGeometryValueBinder.bind(AbstractJTSGeometryValueBinder.java:39)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:280)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:275)
at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:57)

So seems that it tries to persist value as Geometry type of PostGIS. But I want to use just simple Point.

5 Answers 5

9

INSTALL THE POSTGIS EXTENSIONS IN YOUR DATABASE.

The error you are encountering is because you have not installed anything on your database that Hibernate can relate to. It's postgres that is complaining, viz:

org.postgresql.util.PSQLException: Unknown type geometry.

Your annotations and configuration say they have a dependency on PostGIS:

<property name="hibernate.dialect"  value="org.hibernate.spatial.dialect.postgis.PostgisDialect" />

So basically you are trying to use an unsupported configuration.

PostgreSQL does not come with all of the possible data types anyone ever thought of, the way Oracle does. So when Hibernate says "I want a 'geometry' PostgreSQL just says "what's a geometry?" PostgreSQL is very extensible so that's what the PostGIS people did - they built an extension. Anyone can install it or run completely without it. The only problem it causes is when someone expects it in the out-of-the-box database rather than it being an add-on.

I suppose you might try to reverse-engineer the PostgreSQL data types and compile them in your database. Geometry is a master superclass for PostGIS, in Java at least and it looks the same in the database. I just don't see why you would set up a configuration when you won't ever get anyone to support it.

@bluish does this help?

Sign up to request clarification or add additional context in comments.

2 Comments

Although you gave a good answer, the OP asked for a solution without PostGIS.
If OP wants to use the postgis dialect, it will only work reliably with postgis installed in the database. Got to get rid of the dialect.
7
+100

I can offer a more universal way through @Embedded Entity (It doesn't depend on the database type!), which I've used on projects.

Example below:

Piece of SQL query for creating some table with LAT and LONG:

CREATE TABLE some_table (
  lat    NUMBER(..., ...),
  long   NUMBER(..., ...),
...
);

Embeddable Point entity:

@Embeddable
public class Point {
    private BigDecimal x;
    private BigDecimal y;
 ...
}

Your custom entity:

@Entity
@Table(name = "some_table")
public class SomeEntity {
    @Embedded
    @AttributeOverrides({
            @AttributeOverride(name = "lat", column = @Column(name = "x")),
            @AttributeOverride(name = "long", column = @Column(name = "y"))
    })
    private Point point;
...
}

2 Comments

then what is your solution when we need polygone and linestring?
@AliReza19330 for these kind of structures I prefer to find a way start using vividsolutions lib, maybe now it works fine with hibernate5, sorry I haven't had any deal with it.
6

You should try to have the type in your db as Geometry, I also haven't managed to do it with mySQL. Geometry works as fine for points..

3 Comments

What do you mean with this? I can't see Geometry data type in my PostgreSQL 9.3
Maybe @foxTox means the PostGIS Geometry data type. Actually Hibernate Spatial doesn’t support the Geography type (see How do I map a 'Geography(POINT, 4326)' type?).
I'm able to save the points as as a geometry type, but it's unreadable when looking at the data in the database. Is there any way around this?
6

As I am not entirely sure of the question, let me try paraphrasing first:

You want to map an entity having a field of type com.vividsolutions.jts.geom.Point to a PostgreSQL database column of type "point" (cf. postgreSQL geometric types) using hibernate, restricting yourself to the "standard" (i.e. hibernate provided) dialect PostgreSQLDialect.

Some research leads me to the conclusion that the above mentioned hibernate supported standard dialect does not support the PostgreSQL point type at all. So you may want to provide your own UserType. Look at Custom types from the hibernate manual or Understanding and writing Hibernate custom user types for an example from a blog.

4 Comments

Thanks Hille. I'm not restricted to com.vividsolutions.jts.geom.Point. If there is another object that can map PostgreSQL point type, it would be ok. If I have to implement a UserType, I wonder if it would be better to use 2 double fields for lat and long instead. But I fear I'll loose some useful functions available for point type.
a) Meant to say (edited now), that PostgreSQL "point" type isn't supported at all by the hibernate provided dialects, no matter what Java type you're trying to map to. b) If there's no reason to use PostgreSQL "point" type in the first place, one may try to use a JPA 2.1 AttributeConverter (requires hibernate >= 4.3).
Curious as to the direction you recided to go bluish, even if I'm 3 years late to the party
I think this answer is closest to what the original question asked for. The missing bit is that one should use org.postgresql.geometric.PGpoint from the Postgres driver (driver can serialise it in prepared statements natively) instead of com.vividsolutions.jts.geom.Point. Then implement a UserType for Hibernate as this answer suggests or see this answer for copy-paste example.
0

this link will help you LINK : https://www.compose.com/articles/geofile-everything-in-the-radius-with-postgis/

Beside that, distanceWithin() function take distance in degree which you have to cast to geograph but hibernate Spatial doesn't support so there is another way by which you can achieve this by providing distance in decimal according to your requirement.link is mention below for decimal points.

for decimal convertion LINK : https://en.wikipedia.org/wiki/Decimal_degrees

1 Comment

Links will die over time. When that happens to the links you have shared, your answer will point to broken links. I suggest that you could write at least a summary to the links.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.