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)
Related
I am using JPA/Hibernate. So I wanna to do nullCheck in JPQL, but when I do that it does not determine dataType.
JPQL Query:
#Query("select a from Attribute a where :attributeId is null OR a.id = :attributeId")
Page<Attribute> findByAttributeId(#Param("attributeId") UUUID attributeId);
EXCEPTION:
Caused by: org.postgresql.util.PSQLException: ERROR: could not
determine data type of parameter $1
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2532)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2267)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:312)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:448)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:369)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:153)
at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:103)
at jdk.internal.reflect.GeneratedMethodAccessor582.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114)
at com.sun.proxy.$Proxy398.executeQuery(Unknown Source)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:60)
... 114 common frames omitted
I searched a lot on Internet on this topic, but can not find soluthion.
I do not want to handle it in service layer.
I tried:
PostgreSql CAST function
check as String
#Type annotation.
Is there anyway to check UUID null Value in JPQL?
After a bit investigation on Internet, I found the solution.
As PostgreSQL can not determine dataType, we can declare it from before as TypedParameterValue.
TypedParameterValue attributeId = new TypedParameterValue(PostgresUUIDType.INSTANCE, UUIDUtil.toUUID(attributeId));
Page<Attribute> attributes = attributeRepo.findByAttributeId(attributeId);
Then in JPQL for nullChecking, cast to org.hibernate.type.PostgresUUIDType:
( In IDE, it can be shown as error, but it compiles actually)
#Query("select a from Attribute a where (cast(:attributeId as org.hibernate.type.PostgresUUIDType) OR a.id = :attributeId)")
Page<Attribute> findByAttributeId(#Param("attributeId") TypedParameterValue attributeId);
In Native Query:
#Query(value = "select * from attribute a where (cast(:attributeId as uuid) OR a.id = :attributeId)",nativeQuery = true)
List<Attribute> findByAttributeId(#Param("attributeId") TypedParameterValue attributeId);
I had a similar error with JPA 3.0 + EclipseLink + PostgreSQL and was caused because something about automatic casting of parameters. Try adding a stringtype=unspecified to your connection URL:
jdbc:postgresql://SERVER:5432/mydatabase?stringtype=unspecified
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
I am faced with very strange problem, and can't find a way to resolve it. I wrote the following HQL in intellij's HQL Console
update NewsEntity ne set ne.main=false where ne.main=true
StackTrace
java.lang.IllegalArgumentException: node to traverse cannot be null!
at org.hibernate.hql.ast.util.NodeTraverser.traverseDepthFirst(NodeTraverser.java:31)
at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:254)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:157)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:111)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)
in RemoteSessionImpl.createQuery(RemoteSessionImpl.java:50)
in RemoteUtil.executeWithClassLoader(RemoteUtil.java:122)
in RemoteUtil$2$1.invoke(RemoteUtil.java:81)
in HibernateEngine.createQuery(HibernateEngine.java:142)
When I write a delete query I don't have the same problem.
I have based this query around the following article HQL update query. But, can't seem to figure out why I am still having this problem.
The idea of an ORM like Hibernate is to avoid such update queries.
You've just to load the object from the db, change the field and then Hibernate will update the object for out.
Query query = session.createQuery("from NewsEntity ne where ne.main = true");
NewsEntity newsEntity = (NewsEntity) query.uniqueResult();
newsEntity.setMain=false;
//Hibernate will update the object
If there're more objects:
List<NewsEntity> newsEntities = (List<NewsEntity>) query.list();
for(NewsEntity entity : newsEntities)
{
entity.setMain=false;
}
Hibernate also supports DML statements, so to do an update query you should do:
Query query = session.createQuery("your update query");
int result = query.executeUpdate();
This line throws a NPE rooted in SessionFactoryImpl#getReturnTypes method:
Query q = em.createQuery("DELETE FROM Table t WHERE row = :row"), Table.class);
To be more specific the method returning the null value is HQLQueryPlan#getReturnMetadata(), that's why this instruction in SessionFactoryImpl#getReturnTypes fails:
return queryPlanCache.getHQLQueryPlan( queryString, false, CollectionHelper.EMPTY_MAP ).getReturnMetadata().getReturnTypes();
For some reason the selects on that table are working fine, and I recall seeing a delete work as well on the same table, but I don't know where something might have been lost or changed. The last thing I remember doing was removing all rows from the table, but I don't think that has anything to do with the issue.
Any idea what might be wrong?
This one did work:
Query q = em.createNativeQuery("DELETE FROM Table t WHERE row = ?");
But I still don't know why the other one does not, and as I said, the selects do work fine.
Here is the stack trace:
java.lang.NullPointerException
at org.hibernate.impl.SessionFactoryImpl.getReturnTypes(SessionFactoryImpl.java:812)
at org.hibernate.impl.AbstractQueryImpl.getReturnTypes(AbstractQueryImpl.java:193)
at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:278)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
at $Proxy87.createQuery(Unknown Source)
at com.xyz.persistence.dao.myDAO.deleteStuff(myDao.java:652)
because your DELETE query won't return a 'type' the query won't accept the resultClass parameter, Table.class
its a kooky api
Check your domain object Table. Hibernate is not being able to recover metadata for that object, so may be the problem is there. If you're using JPA check your persistence.xml file and ensure your domain object is included.
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.