HHH-14932 Use the correct WKB Dialect

This commit is contained in:
Karel Maesen 2022-02-02 20:53:54 +01:00
parent 6fae23a4dc
commit 29b896bace
10 changed files with 114 additions and 35 deletions

View File

@ -53,10 +53,11 @@ public class PGGeometryTypeDescriptor implements SqlTypeDescriptor {
if ( object == null ) { if ( object == null ) {
return null; return null;
} }
ByteBuffer buffer = null; ByteBuffer buffer;
if ( object instanceof PGobject ) { if ( object instanceof PGobject ) {
String pgValue = ( (PGobject) object ).getValue(); String pgValue = ( (PGobject) object ).getValue();
assert pgValue != null;
if ( pgValue.startsWith( "00" ) || pgValue.startsWith( "01" ) ) { if ( pgValue.startsWith( "00" ) || pgValue.startsWith( "01" ) ) {
//we have a WKB because this pgValue starts with the bit-order byte //we have a WKB because this pgValue starts with the bit-order byte
buffer = ByteBuffer.from( pgValue ); buffer = ByteBuffer.from( pgValue );
@ -91,7 +92,7 @@ public class PGGeometryTypeDescriptor implements SqlTypeDescriptor {
return new ValueBinder<X>() { return new ValueBinder<X>() {
@Override @Override
public final void bind(PreparedStatement st, X value, int index, WrapperOptions options) public void bind(PreparedStatement st, X value, int index, WrapperOptions options)
throws SQLException { throws SQLException {
if ( value == null ) { if ( value == null ) {
st.setNull( index, Types.OTHER ); st.setNull( index, Types.OTHER );
@ -102,7 +103,7 @@ public class PGGeometryTypeDescriptor implements SqlTypeDescriptor {
} }
@Override @Override
public final void bind(CallableStatement st, X value, String name, WrapperOptions options) public void bind(CallableStatement st, X value, String name, WrapperOptions options)
throws SQLException { throws SQLException {
if ( value == null ) { if ( value == null ) {
st.setNull( name, Types.OTHER ); st.setNull( name, Types.OTHER );
@ -112,21 +113,21 @@ public class PGGeometryTypeDescriptor implements SqlTypeDescriptor {
} }
} }
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) private void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
throws SQLException { throws SQLException {
final PGobject obj = toPGobject( value, options ); final PGobject obj = toPGobject( value, options );
st.setObject( index, obj ); st.setObject( index, obj );
} }
protected void doBind(CallableStatement st, X value, String name, WrapperOptions options) private void doBind(CallableStatement st, X value, String name, WrapperOptions options)
throws SQLException { throws SQLException {
final PGobject obj = toPGobject( value, options ); final PGobject obj = toPGobject( value, options );
st.setObject( name, obj ); st.setObject( name, obj );
} }
private PGobject toPGobject(X value, WrapperOptions options) throws SQLException { private PGobject toPGobject(X value, WrapperOptions options) throws SQLException {
final WkbEncoder encoder = Wkb.newEncoder( Wkb.Dialect.POSTGIS_EWKB_1 ); final WkbEncoder encoder = Wkb.newEncoder( wkbDialect );
final Geometry geometry = javaTypeDescriptor.unwrap( value, Geometry.class, options ); final Geometry<?> geometry = javaTypeDescriptor.unwrap( value, Geometry.class, options );
final String hexString = encoder.encode( geometry, ByteOrder.NDR ).toString(); final String hexString = encoder.encode( geometry, ByteOrder.NDR ).toString();
final PGobject obj = new PGobject(); final PGobject obj = new PGobject();
obj.setType( "geometry" ); obj.setType( "geometry" );

View File

@ -23,7 +23,7 @@ import org.hibernate.spatial.SpatialFunction;
public class PostgisPG82Dialect extends PostgreSQL82Dialect implements SpatialDialect { public class PostgisPG82Dialect extends PostgreSQL82Dialect implements SpatialDialect {
transient private PostgisSupport support = new PostgisSupport(); final transient private PostgisSupport support = new PostgisSupport();
/** /**
* Creates an instance * Creates an instance
@ -45,7 +45,7 @@ public class PostgisPG82Dialect extends PostgreSQL82Dialect implements SpatialDi
typeContributions, typeContributions,
serviceRegistry serviceRegistry
); );
support.contributeTypes( typeContributions, serviceRegistry ); support.contributeTypes( typeContributions, serviceRegistry, PGGeometryTypeDescriptor.INSTANCE_WKB_1 );
} }
@Override @Override

View File

@ -23,7 +23,7 @@ import org.hibernate.spatial.SpatialFunction;
public class PostgisPG91Dialect extends PostgreSQL91Dialect implements SpatialDialect { public class PostgisPG91Dialect extends PostgreSQL91Dialect implements SpatialDialect {
transient private PostgisSupport support = new PostgisSupport(); final transient private PostgisSupport support = new PostgisSupport();
/** /**
* Creates an instance * Creates an instance
@ -45,7 +45,7 @@ public class PostgisPG91Dialect extends PostgreSQL91Dialect implements SpatialDi
typeContributions, typeContributions,
serviceRegistry serviceRegistry
); );
support.contributeTypes( typeContributions, serviceRegistry ); support.contributeTypes( typeContributions, serviceRegistry, PGGeometryTypeDescriptor.INSTANCE_WKB_1 );
} }
@Override @Override

View File

@ -23,7 +23,7 @@ import org.hibernate.spatial.SpatialFunction;
public class PostgisPG92Dialect extends PostgreSQL92Dialect implements SpatialDialect { public class PostgisPG92Dialect extends PostgreSQL92Dialect implements SpatialDialect {
transient private PostgisSupport support = new PostgisSupport(); final transient private PostgisSupport support = new PostgisSupport();
/** /**
* Creates an instance * Creates an instance
@ -45,7 +45,7 @@ public class PostgisPG92Dialect extends PostgreSQL92Dialect implements SpatialDi
typeContributions, typeContributions,
serviceRegistry serviceRegistry
); );
support.contributeTypes( typeContributions, serviceRegistry ); support.contributeTypes( typeContributions, serviceRegistry, PGGeometryTypeDescriptor.INSTANCE_WKB_1 );
} }
@Override @Override

View File

@ -23,7 +23,7 @@ import org.hibernate.spatial.SpatialFunction;
public class PostgisPG93Dialect extends PostgreSQL93Dialect implements SpatialDialect { public class PostgisPG93Dialect extends PostgreSQL93Dialect implements SpatialDialect {
transient private PostgisSupport support = new PostgisSupport(); final transient private PostgisSupport support = new PostgisSupport();
/** /**
* Creates an instance * Creates an instance
@ -45,7 +45,7 @@ public class PostgisPG93Dialect extends PostgreSQL93Dialect implements SpatialDi
typeContributions, typeContributions,
serviceRegistry serviceRegistry
); );
support.contributeTypes( typeContributions, serviceRegistry ); support.contributeTypes( typeContributions, serviceRegistry, PGGeometryTypeDescriptor.INSTANCE_WKB_1 );
} }
@Override @Override

View File

@ -23,7 +23,7 @@ import org.hibernate.spatial.SpatialFunction;
public class PostgisPG94Dialect extends PostgreSQL94Dialect implements SpatialDialect { public class PostgisPG94Dialect extends PostgreSQL94Dialect implements SpatialDialect {
transient private PostgisSupport support = new PostgisSupport(); final transient private PostgisSupport support = new PostgisSupport();
/** /**
* Creates an instance * Creates an instance
@ -45,7 +45,7 @@ public class PostgisPG94Dialect extends PostgreSQL94Dialect implements SpatialDi
typeContributions, typeContributions,
serviceRegistry serviceRegistry
); );
support.contributeTypes( typeContributions, serviceRegistry ); support.contributeTypes( typeContributions, serviceRegistry, PGGeometryTypeDescriptor.INSTANCE_WKB_1 );
} }
@Override @Override

View File

@ -25,7 +25,7 @@ public class PostgisPG95Dialect extends PostgreSQL95Dialect implements PGSpatial
public PostgisPG95Dialect() { public PostgisPG95Dialect() {
super(); super();
registerColumnType( registerColumnType(
PGGeometryTypeDescriptor.INSTANCE_WKB_1.getSqlType(), PGGeometryTypeDescriptor.INSTANCE_WKB_2.getSqlType(),
"GEOMETRY" "GEOMETRY"
); );
for ( Map.Entry<String, SQLFunction> entry : functionsToRegister() ) { for ( Map.Entry<String, SQLFunction> entry : functionsToRegister() ) {

View File

@ -23,7 +23,7 @@ import org.hibernate.spatial.SpatialFunction;
public class PostgisPG9Dialect extends PostgreSQL9Dialect implements SpatialDialect { public class PostgisPG9Dialect extends PostgreSQL9Dialect implements SpatialDialect {
transient private PostgisSupport support = new PostgisSupport(); final transient private PostgisSupport support = new PostgisSupport();
/** /**
* Creates an instance * Creates an instance
@ -31,7 +31,7 @@ public class PostgisPG9Dialect extends PostgreSQL9Dialect implements SpatialDial
public PostgisPG9Dialect() { public PostgisPG9Dialect() {
super(); super();
registerColumnType( registerColumnType(
PGGeometryTypeDescriptor.INSTANCE_WKB_1.getSqlType(), PGGeometryTypeDescriptor.INSTANCE_WKB_2.getSqlType(),
"GEOMETRY" "GEOMETRY"
); );
for ( Map.Entry<String, SQLFunction> entry : support.functionsToRegister() ) { for ( Map.Entry<String, SQLFunction> entry : support.functionsToRegister() ) {

View File

@ -20,6 +20,7 @@ import org.hibernate.spatial.SpatialDialect;
import org.hibernate.spatial.SpatialFunction; import org.hibernate.spatial.SpatialFunction;
import org.hibernate.spatial.SpatialRelation; import org.hibernate.spatial.SpatialRelation;
import org.hibernate.spatial.dialect.SpatialFunctionsRegistry; import org.hibernate.spatial.dialect.SpatialFunctionsRegistry;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/** /**
* Created by Karel Maesen, Geovise BVBA on 29/10/16. * Created by Karel Maesen, Geovise BVBA on 29/10/16.
@ -36,20 +37,28 @@ public class PostgisSupport implements SpatialDialect, Serializable {
postgisFunctions = new PostgisFunctions(); postgisFunctions = new PostgisFunctions();
} }
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) { public void contributeTypes(
typeContributions.contributeType( new GeolatteGeometryType( PGGeometryTypeDescriptor.INSTANCE_WKB_1 ) ); TypeContributions typeContributions,
typeContributions.contributeType( new JTSGeometryType( PGGeometryTypeDescriptor.INSTANCE_WKB_1 ) ); ServiceRegistry serviceRegistry,
SqlTypeDescriptor wkbType) {
typeContributions.contributeType( new GeolatteGeometryType( wkbType ) );
typeContributions.contributeType( new JTSGeometryType( wkbType ) );
typeContributions.contributeJavaTypeDescriptor( GeolatteGeometryJavaTypeDescriptor.INSTANCE ); typeContributions.contributeJavaTypeDescriptor( GeolatteGeometryJavaTypeDescriptor.INSTANCE );
typeContributions.contributeJavaTypeDescriptor( JTSGeometryJavaTypeDescriptor.INSTANCE ); typeContributions.contributeJavaTypeDescriptor( JTSGeometryJavaTypeDescriptor.INSTANCE );
} }
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
contributeTypes( typeContributions, serviceRegistry, PGGeometryTypeDescriptor.INSTANCE_WKB_2 );
}
public SpatialFunctionsRegistry functionsToRegister() { public SpatialFunctionsRegistry functionsToRegister() {
return postgisFunctions; return postgisFunctions;
} }
public boolean isSpatial(int typeCode){ public boolean isSpatial(int typeCode) {
return typeCode == Types.OTHER || typeCode == PGGeometryTypeDescriptor.INSTANCE_WKB_1.getSqlType(); return typeCode == Types.OTHER || typeCode == PGGeometryTypeDescriptor.INSTANCE_WKB_2.getSqlType();
} }
/** /**
@ -117,17 +126,13 @@ public class PostgisSupport implements SpatialDialect, Serializable {
*/ */
@Override @Override
public String getSpatialAggregateSQL(String columnName, int aggregation) { public String getSpatialAggregateSQL(String columnName, int aggregation) {
switch ( aggregation ) { if ( aggregation == SpatialAggregate.EXTENT ) {
case SpatialAggregate.EXTENT: return "st_extent(" + columnName + ")::geometry";
final StringBuilder stbuf = new StringBuilder();
stbuf.append( "st_extent(" ).append( columnName ).append( ")::geometry" );
return stbuf.toString();
default:
throw new IllegalArgumentException(
"Aggregation of type "
+ aggregation + " are not supported by this dialect"
);
} }
throw new IllegalArgumentException(
"Aggregation of type "
+ aggregation + " are not supported by this dialect"
);
} }
/** /**

View File

@ -0,0 +1,73 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.spatial.dialect.postgis;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Before;
import org.junit.Test;
import org.geolatte.geom.G2D;
import org.geolatte.geom.Point;
import static org.geolatte.geom.builder.DSL.g;
import static org.geolatte.geom.builder.DSL.point;
import static org.geolatte.geom.crs.CoordinateReferenceSystems.WGS84;
import static org.junit.Assert.assertEquals;
@TestForIssue(jiraKey = "HHH-14932")
@RequiresDialect(PostgisPG95Dialect.class)
public class TestWKBPostgis221 extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Foo.class };
}
@Before
public void setup() {
inTransaction( session -> session.persist( new Foo(
1,
point( WGS84 )
) ) );
}
@Test
public void test() {
inTransaction( session -> {
List<Foo> list = session
.createQuery( "from Foo", Foo.class )
.getResultList();
assertEquals( point( WGS84 ), list.get( 0 ).point );
} );
}
@Entity(name = "Foo")
@Table(name = "Foo")
public static class Foo {
@Id
long id;
Point<G2D> point;
public Foo() {
}
public Foo(long id, Point<G2D> point) {
this.id = id;
this.point = point;
}
}
}