Hibernate Spatial - 'Invalid endian flag value encountered' Exception - java

I'm trying to run a simple query in Hibernate Spatial 4.0 on PostgreSQL 9.3. I have a number of objects in a table with latitude/longitude values, and I'm trying to query objects that fall within a given radius of a particular latitude/longitude. The geometry values seem to be persisted without any problem, and are defined like this in my entity class:
#Column(columnDefinition = "Geometry", nullable = true)
#Type(type = "org.hibernate.spatial.GeometryType")
private Point coordinates = null;
I don't have any errors when persisting objects with the coordinates value set. However, when I run a query, I see the following Exception:
javax.servlet.ServletException: javax.servlet.ServletException: javax.ejb.EJBTransactionRolledbackException: org.hibernate.exception.GenericJDBCException: could not extract ResultSet
<snip />
org.postgresql.util.PSQLException: ERROR: Invalid endian flag value encountered.
org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2157)
org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1886)
org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:555)
org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:417)
org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:302)
org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:462)
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:56)
org.hibernate.loader.Loader.getResultSet(Loader.java:2031)
org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1832)
org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1811)
org.hibernate.loader.Loader.doQuery(Loader.java:899)
org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
org.hibernate.loader.Loader.doList(Loader.java:2516)
org.hibernate.loader.Loader.doList(Loader.java:2502)
org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2332)
org.hibernate.loader.Loader.list(Loader.java:2327)
org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:490)
org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355)
org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195)
org.hibernate.internal.SessionImpl.list(SessionImpl.java:1268)
org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:264)
The query I'm running looks like this:
Query query = this.entityManager
.createQuery(
"SELECT v FROM MyEntity v WHERE within(v.coordinates, :filter) = true",
MyEntity.class);
query.setParameter("filter", point);
I came across this question on StackOverflow that mentions the same error, but I'm declaring my coordinates property the same way that is mentioned in the answer and still get this error.
For the record, I've tried using PostGIS 1.5.2 and PostGIS 2.1.0. I've also tried different version of my PostgreSQL JDBC driver, from 8.4 to 9.3. Regardless of the library version I still encounter this issue.
Can anyone shed any light on what could be happening here? Is my query wrong? Is my property not defined correctly? Is there something else I should be trying? I'm completely stuck and at a loss for what could be the issue here. Any advice would be GREATLY appreciated.

Try this:
#Column(columnDefinition="Geometry")
#Type(type = "org.hibernatespatial.GeometryUserType")
private Point point;

I solved by adding the below dependency
<dependency>
<groupId>org.locationtech.jts</groupId>
<artifactId>jts-core</artifactId>
<version>1.16.1</version>
</dependency>
instead of my old dependency: com.vividsolutions

Related

Quarkus hibernate Exception in native mode

I'am setting up a simple Quarkus application using hibernate for testing Quarkus capabilities.
It contains a simple hibernate mapping
#Entity
Class AnEntity{
public double[] data;
}
It maps to the postgresql table anentity(data bytea).
This is fine for me and works well when running on JVM: zero problem on this side. I can read easily the content of the table using a NativeQuery.
Query query = em.createNativeQuery("select * from anentity",AnEntity.class);
List<AnEntity> resultList = query.getResultList();
for (AnEntity anEntity: resultList) {
System.out.println(anEntity.data);
}
The behavior here is that the content of the data array is serialized/deserialized using "standard" java serialization when reading/writing the data field from and to the database.
Now when compiling in native mode, I have a serialization related exception that follows:
ERROR [io.qua.run.Application] (main) Failed to start application (with profile prod): java.io.StreamCorruptedException: invalid type code: 40
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1712)
at java.io.ObjectInputStream.readArray(ObjectInputStream.java:2103)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1669)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:493)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:451)
at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:225)
at org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:287)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:138)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:113)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:29)
at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$2.doExtract(VarbinaryTypeDescriptor.java:60)
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:257)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:253)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:243)
at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:329)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:3214)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1887)
at org.hibernate.loader.Loader.hydrateEntityState(Loader.java:1811)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1784)
at org.hibernate.loader.Loader.getRow(Loader.java:1624)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:748)
at org.hibernate.loader.Loader.getRowsFromResultSet(Loader.java:1047)
I tried to register double[].class in a #RegisterForReflection annotation, changing double[] to Double[] but it did not help.
I'am not sure what's wrong here. It looks like the Java default serialization/deserialization is not working well in native mode, and I'am wondering how to solve this.
Thanks for any hints/pointer. I have the feeling it is a simple problem of a missing declaration or configuration parameter somewhere, at least I hope so :)
I'll double check known issues with Java deserialization in native mode.
Solved!
After more investigations it was a simple matter of registering the double[] class in native image builder serialization configuration file.
Added this line in the quarkus application.properties:
quarkus.native.additional-build-args = -H:SerializationConfigurationResources=serialization-config.json
and serialization-config.json being simply
[
{"name":"double[]"}
]

Set random seed on Postgres using hibernate

I'm not very familiar with Hibernate, but I need to set the random seed on a PostgreSQL database using Hibernate.
This is what I'm trying to run:
String seedSql = "select setseed(0.123)";
Query seedQuery = entityManager.createQuery(seedSql);
seedQuery.getSingleResult();
However, this query does not return any entity mapped by Hibernate, thus I'm receiving the following error:
org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode (...)
Any suggestions?
According to the docs, createQuery() takes a JPQL string, and apparently doesn't know what to do with your Postgres function call.
To run an SQL query, use createNativeQuery() instead.
After some trial and error I noticed that I had to use .createNativeQuery() since setseed() is a function from PostgreSQL:
String seedsql = "select cast(setseed(0.123) as text)";
Query seedQuery = DatabaseInterface.getEm().createNativeQuery(seedsql);
seedQuery.setMaxResults(1).getSingleResult();
I used cast(setseed(0.123) as text) to avoid another error:
org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111

Hibernate and Postgres positional parameteres mismatch

I am currently maintaining a legacy application which uses some old technologies: Hibernate 3.2, Spring 2.5 and the like.
I've been fighting the last days with an exception. I've managed to isolate a simple example:
private void test(String username) {
String sql = "from org.ojade.aas.authentication.model.User u " +
"where u.aasPrincipalName = ?";
Session session = sessionFactory.getCurrentSession();
QueryImpl query = (QueryImpl) session.createQuery(sql);
query.setParameter(0, username);
List list = query.list();
log.debug("list = {}", list);
}
The execution of this code throws an exception when query.list() is executed.
Caused by: org.postgresql.util.PSQLException: No value specified for parameter 2.
at org.postgresql.core.v3.SimpleParameterList.checkAllParametersSet(SimpleParameterList.java:102)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:166)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:389)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:330)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:240)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:92)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:187)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1791)
at org.hibernate.loader.Loader.doQuery(Loader.java:674)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.doList(Loader.java:2217)
... 120 more
There is no parameter 2. If I change the query to use named parameters it works, but I can't change the original code (is part of a compiled library).
I've set Hibernate to show me the SQL. It is executing this:
SELECT
user0_.ID_PRINCIPAL AS ID1_3_,
user0_.VERSION AS VERSION3_,
user0_.NO_PRINCIPAL AS NO4_3_,
user0_.IN_BLOQUEO AS IN5_3_,
user0_.IN_ACTIVO AS IN6_3_
FROM JAAS_PRINCIPAL user0_
WHERE user0_.TT_DISCRIMINANTE = 'USER' AND user0_.NO_PRINCIPAL =?
Which seems ok.
Any idea what the problem may be?
This old bug reported against the postgresql-8.1-405.jdbc3.jar driver informs that if you have /* */ comments including a ? in the query, the parser won't understand that it's not a placeholder, but just part of the comment. Apparently other characters such as dollar signs also caused problems.
As given in the original bug report, this can be solved with named parameters, fixing comments (in this case the comments were generated by Hibernate, so turning off Hibernate comments with property hibernate.use_sql_comments=false fixes it) or by upgrading the driver to handle it more gracefully (no idea which version it was fixed though).
Quite a catch to come across this in 2017! :)

Hibernate transformer null pointer exception

I'm trying to get hibernate's ResultTransformer to work for fetching an entire table but keep getting a NullPointerException.
List result = session.createQuery(
"FROM com.maps.model.Book")
.setResultTransformer( Transformers.aliasToBean(Book.class))
.list();
Is there a way to get this to work for an entire table using HQL?
(The reason I'm doing this is that I have a project with 50 plus tables which I need to cache and I don't want to write 50 different methods.)
EDIT: the exception stacktrace:
java.lang.NullPointerException
at org.hibernate.transform.AliasToBeanResultTransformer.initialize(AliasToBeanResultTransformer.java:116)
at org.hibernate.transform.AliasToBeanResultTransformer.transformTuple(AliasToBeanResultTransformer.java:85)
at org.hibernate.hql.internal.HolderInstantiator.instantiate(HolderInstantiator.java:95)
at org.hibernate.loader.hql.QueryLoader.getResultList(QueryLoader.java:438)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2263)
at org.hibernate.loader.Loader.list(Loader.java:2258)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:470)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:196)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1161)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
at com.maps.manager.DatabaseManager.findAll(DatabaseManager.java:65)
at com.maps.manager.DatabaseManager.main(DatabaseManager.java:40)

generating UUID from dual table

I want to generate UUID for a unique string, i am using the following code:-
thread.createSession();
HexGenerator gen1 = new HexGenerator();
gen1.setHexId("2");
thread.ses.save(gen1);
gen1 = (HexGenerator) thread.ses.load(HexGenerator.class, gen1.getHexId());
System.out.println("gen1-->" + gen1.getHexId());
thread.commit();
Below is my hibernate file:-
<class name="entity.HexGenerator" table="dual">
<id name="hexId" type="string" unsaved-value="null">
<generator class="uuid.hex"/>
</id>
</class>
UUId is generated properly, but i am getting an error when the complete transaction is committed. as in the following error comes.
Exception in thread "main" - Could not synchronize database state with session
org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.ofss.test.hibernate.HibernateThread.commit(HibernateThread.java:29)
at com.ofss.test.hibernate.HibernateThread.main(HibernateThread.java:57)
Caused by: java.sql.BatchUpdateException: ORA-00904: "HEXID": invalid identifier
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10698)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
... 9 more
org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.ofss.test.hibernate.HibernateThread.commit(HibernateThread.java:29)
at com.ofss.test.hibernate.HibernateThread.main(HibernateThread.java:57)
Caused by: java.sql.BatchUpdateException: ORA-00904: "HEXID": invalid identifier
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10698)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
You can't insert or update on the Oracle dual virtual table. You just can use it at select queries.
So, your line thread.ses.save(gen1) is what generates the error. I think that if you just delete this line, the error will be fixed.
But I don't really understand why you need to access the database to generate your UUID, which seems to be generated at the HexGenerator class (or maybe at the "uuid.gen" class referenced at the hibernate file).
To overcome the above problem, i mean to generate the UUID, now I have decided to use two method, either to use java.util.UUID.randomUUID() or to write my own logic to generate the same using bits array and then randomizing it.
first, your code looks a little bit strange. You create instance of HexGenerator:
HexGenerator gen1 = new HexGenerator();
use it and immediately override using some unknown for me API that uses dynamic class loading.
thread.ses.load(HexGenerator.class, gen1.getHexId())
Then you call getHexId() again. I believe that code
new HexGenerator().getHexId()
will generate ID that you need.
But I think it is not yet the reason for failure. Unfortunately you did not provide any information about you DB schema. I believe that you ID is simply defined as number, it cannot accept strings. Check it again and please provide more details if this is not the reason.

Categories