QueryDSL with Lob Field - java

I've an entity class with lob field called RAW (eclipselink JPA provider and sql server), also I'm using querydsl to query to database. But I've this problem...
javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: The text data type cannot be selected as DISTINCT because it is not comparable.
Error Code: 421
Call: SELECT DISTINCT ID, ALTA, ANIO, FECHARECEPCION, INSTITUCION, MES, RAW, VERSION FROM ARCHIVO WHERE (FECHARECEPCION BETWEEN ? AND ?)
bind => [2013-01-01 00:00:00.0, 2014-01-31 23:59:59.0]
Query: ReadAllQuery(referenceClass=Archivo sql="SELECT DISTINCT ID, ALTA, ANIO, FECHARECEPCION, INSTITUCION, MES, RAW, VERSION FROM ARCHIVO WHERE (FECHARECEPCION BETWEEN ? AND ?)")
Any suggestions?
The query is
QArchivo archivo = QArchivo.archivo;
JPAQuery query = from(archivo);
query.where(archivo.institucion.eq(institucion));
query.where(archivo.fechaRecepcion.between(fechaInicio, fechaTermino));
List<Archivo> resultado = query.list(archivo);
return resultado;

It is odd that it is using a DISTINCT when you called list() not listDistinct(), and seemed to not have called distinct(). Double check that you are not calling distinct() anywhere. DISTINCT in normally only used with joins, so since you are not using any, it is very odd that it is used.
You could also try the same query through JPQL or the Criteria API, it should not use DISTINCT unless to specify it.
If you want to use DISTINCT and have a LOB, then you cannot select the LOB. You can either put the LOB in its own table and reference it through a OneToOne, or make its fetch=LAZY.
You can also reword the query to use a sub-select so that the distinct in only in the sub-select.
i.e.
Select a from Archivo a where exists (select a2 from Archivo a2 where ... and a = a2))

Related

JPA very strange error when change query parameter

I'm having an strange issue in this query.
Code:
em2=getNewEntityManager();
(...)
Query query2 = em2.createNativeQuery("SELECT DISTINCT ID_ZONA FROM VWG_REL_USUARIOS_ZONAS WHERE DNI like '"+dni+"'") ;
List <Long> permisos = query2.getResultList();
(...)
If "dni" equals to: "%" the query goes normal, but if "dni" is "%123456789" gives this error
javax.persistence.PersistenceException: Exception [EclipseLink-4002]
(Eclipse Persistence Services - 2.5.0.v20130507-3faac2b):
org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: sql string is not a dml statement
Error Code: 17129
Call: SELECT DISTINCT ID_ZONA FROM VWG_REL_USUARIOS_ZONAS WHERE DNI like '%XX828747B'
Query: DataReadQuery(sql="SELECT DISTINCT ID_ZONA FROM VWG_REL_USUARIOS_ZONAS WHERE DNI like '%XX828747B'")
And if I copy the exact query above in my SQL developer, it works as magic.
I've tried with the "createQuery" with the entities and all the stuff, same error.
Thanks a lot
Try assigning the value to a parameter, such as:
String dni = "some value";
Query query2 = em2.createNativeQuery("SELECT DISTINCT ID_ZONA FROM VWG_REL_USUARIOS_ZONAS WHERE DNI like :param") ;
query2.setParamter("param", dni);
List <Long> permisos = query2.getResultList();
Update: In EclipseLink, Only indexed parameters are supported, named parameters are not supported.
Finally I got it, it is working now.
I was changing DNI value in debugging mode in eclipse, to fit the test I want to do. So a session validator invalidated my the user as some of the data "by magic" changed in an strange way. To do the test without compiling every time, I have to change DNI value BEFORE session is created.
What I don't know is why is it giving so specific SQL exception when the error originated validating the session. Something like "session is invalid" would have saved me a couple of hours...
Thanks all for your time

How to execute a JPA Bulk Update statement which takes a List as a parameter value

I have an Update Query that looks like this
UPDATE
table_name
SET
column_name = ?
WHERE
column_name = ? AND id in (?)
So the JPA transaction is
em.createNativeQuery(Update_QUERY)
.setParameter(1, updatedStatus)
.setParameter(2, currentStatus)
.setParameter(3, ids)
.executeUpdate();
The Input to the method is List id, currentStatus, and updatedStatus
How do I pass the List as a single parameter, if I convert the List to a comma-separated String I get the error Specified text is not number as strings is not allowed in the In clause.
How do I pass the List as a single parameter
An example approach:
String jpql = "UPDATE NameEntity ne " +
"SET ne.valstring = :updated_status " +
"WHERE ne.valstring = :current_status AND ne.id IN :ids";
em.createQuery(jqpl)
.setParameter("updated_status", updatedStatus)
.setParameter("current_status", currentstatus)
.setParameter("ids", Arrays.asList(ids))
.executeUpdate();
Three simple rules:
Use native SQL for bulk update / delete on tables that are not mapped to entities.
Native SQL queries work directly on database tables bypassing the persistence context (a set of managed entities), so it is safe to use such queries if a given database table has no corresponding entity.
Use JPQL for bulk update / delete on tables that are mapped to entities
In case of a given database table is mapped by an entity, using a SQL update / delete will lead to inconsistency between persistence context and the underlying database, so use JQPL counterparts instead and the persistence provider will take care of consistency.
Bulk update / delete should be executed as the first operation within the transaction or ideally in its own transaction.
Setting a List parameter
The JPA Query interface setParameter method that accepts an Object parameter:
Query setParameter(String name, Object value)
can take a List as the parameter value.
This works in the same way for JPQL, Criteria API, or bulk update and delete queries:
List<Post> posts = entityManager.createNativeQuery("""
UPDATE
post
SET
status = :newStatus
WHERE
status = :oldStatus AND
id IN :ids
""", Post.class)
.setParameter("oldStatus", PostStatus.PENDING)
.setParameter("newStatus", PostStatus.APPROVED)
.setParameter("ids", List.of(1L, 2L, 3L))
.executeUpdate();
For more details about executing bulk update and delete statements with JPA and Hibernate, check out this article as well.

build a org.eclipse.persistence.queries.ReportQuery from a javax.persistence.Query

I am trying to use a single named query both for obtaining a set of results and to count the available amount of data. I have a named JPQL query:
#NamedQuery(name = "query.all.absences.by.name", query = "SELECT a FROM Absence a WHERE a.name = :name")
When I obtain the Absences I'm invoking the query like this:
final Query q = em.createNamedQuery("query.all.absences.by.name");
q.setParameter("name","aRandomAbsenceName");
//maxResults and firstResult are coming as parameters, are computed in another method
q.setMaxResults(maxResults);
q.setFirstResult(firstResult);
q.getResultList() gets me the correct result set. So far so good.
Now what I want to do is use the same named query to execute a count query.
I'm doing the following:
final Query q = em.createNamedQuery("query.all.absences.by.name");
q.setParameter("name","aRandomAbsenceName");
q.setHint(QueryHints.QUERY_TYPE, "org.eclipse.persistence.queries.ReportQuery");
final ReportQuery test = JpaHelper.getReportQuery(q);
test.addCount();
test.setShouldReturnWithoutReportQueryResult(true);
This approach works fine if my named query does not have parameters. But with parameters, if I execute the ReportQuery defined above I have the following exception:
Exception [EclipseLink-6094] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.QueryException
Exception Description: The parameter name [name] in the query's selection criteria does not match any parameter name defined in the query.
Query: ReportQuery(referenceClass=AbsenceCategory sql="SELECT COUNT(CATEGORY_KEY) FROM ABSENCE_CATEGORY WHERE (CATEGORY_KEY = ?)")
at org.eclipse.persistence.exceptions.QueryException.parameterNameMismatch(QueryException.java:1063)
at org.eclipse.persistence.internal.expressions.ParameterExpression.getValue(ParameterExpression.java:275)
at org.eclipse.persistence.internal.databaseaccess.DatabaseCall.translate(DatabaseCall.java:1000)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:206)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:193)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeSelectCall(DatasourceCallQueryMechanism.java:264)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.selectAllRows(DatasourceCallQueryMechanism.java:646)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRowsFromTable(ExpressionQueryMechanism.java:2611)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllReportQueryRows(ExpressionQueryMechanism.java:2554)
at org.eclipse.persistence.queries.ReportQuery.executeDatabaseQuery(ReportQuery.java:846)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:844)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1040)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:392)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1128)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2871)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1516)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1498)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1449)
How else can I possibly set the parameters to a ReportQuery?
I'm using EclipseLink 2.0.
How are you executing the ReportQuery? You need to call Session.executeQuery(query, arguments) and pass a List of the arguments (order the same as query.getArguments().
You can probably also use the JpaEntityManager createQuery(DatabaseQuery) API to convert the ReportQuery back to a JPA Query, then you can just set the parameter the JPA way.

QuerySyntaxException : Hibernate not recognizing the postgres query syntax in java

I am facing problem of executing the following query in java using hibernate for postgres tables.
The query is made up to retrive the data from 3 tables using Inner Joins.
Query :
QryJourney = "SELECT journey.id , journey.operatingday, journey.linename, journey.scheduledeparture, journey.scheduledeparturestopname, journeydetail.stopname , journeydetail.latitude, journeydetail.longitude FROM journey left join journey_journeydetail ON journey.id = journey_journeydetail.journey_id left JOIN journeydetail ON journey_journeydetail.journeydetails_id = journeydetail.id WHERE journey.id = '155815228' ORDER BY journeydetail.schedulearrival";
as soon as it executes, following exception occured.
Exception :
Exception in thread "main" org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ON near line 1, column 268 [SELECT journey.id , journey.operatingday, journey.linename, journey.scheduledeparture, journey.scheduledeparturestopname, journeydetail.stopname , journeydetail.latitude, journeydetail.longitude FROM de.db.journeyTracker.model.journey left join journey_journeydetail ON journey.id = journey_journeydetail.journey_id left JOIN journeydetail ON journey_journeydetail.journeydetails_id = journeydetail.id WHERE journey.id = '155815228' ORDER BY journeydetail.schedulearrival]
Tis query works 100% fine at postgres while executing on its SQL Pane.
Anybody having any idea?
Regards
Usman
Hibernate queries are written in Hibernate Query Language (HQL) not in native SQL. Rephrase your query in HQL or use a native query to use SQL with Hibernate.
Hibernate is an object-relational mapper. It won't just give you a result set. If you want that, use JDBC directly, using PgJDBC.
If you want native domain objects as query results, use Hibernate with HQL or via a native query mapping. Native queries are fiddlier becuse you have to explicitly tell Hibernate how all the result columns map to your result objects.

Error executing a Query using JPA

I'm trying to sort a resultset using the SQL statement Order by using JPA, on a datetime column data type with this string, on a Mysql database:
Query query = em.createQuery("SELECT e FROM Events e Order by e.EventDateTime;");
Using the createQuery method java returns the error:
SEVERE: Local Exception Stack:
Exception [EclipseLink-8030] (Eclipse Persistence Services - 2.3.0.v20110604-r9504):
org.eclipse.persistence.exceptions.JPQLException
Exception Description: Error compiling the query [Events.findByGameId: SELECT e FROM Events e WHERE e.gameId =
:gameId ORDER BY e.EventDateTime DESC], line 1, column 59: unknown state or association field [EventDateTime] of class [com.jogogestao.entity.Events].
at org.eclipse.persistence.exceptions.JPQLException.unknownAttribute(JPQLException.java:457)
at org.eclipse.persistence.internal.jpa.parsing.DotNode.validate(DotNode.java:88)
at org.eclipse.persistence.internal.jpa.parsing.OrderByItemNode.validate(OrderByItemNode.java:52)
at org.eclipse.persistence.internal.jpa.parsing.OrderByNode.validate(OrderByNode.java:61)
at org.eclipse.persistence.internal.jpa.parsing.ParseTree.validate(ParseTree.java:210)
I tried sorting by the integer type primary and all runs ok...but this is not what I want of course.
Using createNativeQuery the statement runs ok...
Query query = em.createNativeQuery("SELECT * FROM Events Order by EventDateTime;");
The only problem is that the return object is not an Events type object (from the entity) and I can't convert to this type.
Maybe the problem is that JPA does not support sorting on datetime fields?
How can I get around this?
I'm using Netbeans 7.0.1, Glassfish 3.1.1, MySql 5.5.19 Community Server (GPL) and mysql-connector-java-5.1.15-bin.jar.
Thanks!
SELECT e FROM Event e ORDER BY e.eventDateTime
you don't have * - you have to specify the entity you select
don't put a semicolon at the end
use all-lower-case keywords, capital-case entity names, and lower-camel-case property names
name the entity in singular, not plural (Event vs Events)
The message is clear: you don't have an EventDateTime mapped property (or field, if fields are mapped directly) in the entity Events. If you respect the Java conventions, the field/property should be named eventDateTime, and not EventDateTime.

Categories

Resources