I have this Java code (JPA):
String queryString = "SELECT b , sum(v.votedPoints) as votedPoint " +
" FROM Bookmarks b " +
" LEFT OUTER JOIN Votes v " +
" on (v.organizationId = b.organizationId) " +
"WHERE b.userId = 101 " +
"GROUP BY b.organizationId " +
"ORDER BY votedPoint ascending ";
EntityManager em = getEntityManager();
Query query = em.createQuery(queryString);
query.setFirstResult(start);
query.setMaxResults(numRecords);
List results = query.getResultList();
I don't know what is wrong with my query because it gives me this error:
java.lang.NoSuchMethodError: org.hibernate.hql.antlr.HqlBaseParser.recover(Lantlr/RecognitionException;Lantlr/collections/impl/BitSet;)V
at org.hibernate.hql.antlr.HqlBaseParser.fromJoin(HqlBaseParser.java:1802)
at org.hibernate.hql.antlr.HqlBaseParser.fromClause(HqlBaseParser.java:1420)
at org.hibernate.hql.antlr.HqlBaseParser.selectFrom(HqlBaseParser.java:1130)
at org.hibernate.hql.antlr.HqlBaseParser.queryRule(HqlBaseParser.java:702)
at org.hibernate.hql.antlr.HqlBaseParser.selectStatement(HqlBaseParser.java:296)
at org.hibernate.hql.antlr.HqlBaseParser.statement(HqlBaseParser.java:159)
at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:271)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:180)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:134)
at org.hibernate.engine.query.HQLQueryPlan.(HQLQueryPlan.java:101)
at org.hibernate.engine.query.HQLQueryPlan.(HQLQueryPlan.java:80)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:94)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1650)
Thanks.
You definitely have an issue with the version of hibernate and ANTLR jars that you are using. The recover method wasn't present in the ANTLR Parser class until version 2.7.6? If you are using an earlier version of ANTLR, such as 2.7.2, then you will see this problem.
Using maven can cause this sort of situation, where you depend on Hibernate and its transitive dependencies, but something 'closer'; e.g. Struts; providers a different, earlier version of ANTLR and that earlier version gets resolved in your application.
If you can provide the version of jars involved, we would be able to help some more. Once you have fixed the issue with the jar versions, you should get a more revealing error message which shows what is wrong with your HQL expression.
Stab in the dark - Are you sure you have a consistent set of jars - perhaps you need to get the antlr jar that comes with the hibernate distribution you are using...
I've found the problem:
because this is a native query, java classes for this 2 tables must have some special attributes:
in Bookmarks.java class
#OneToMany(mappedBy = "bookmarkId")
private Collection votesCollection;
and in Votes.java class
#JoinColumn(name = "bookmark_id", referencedColumnName = "bookmark_id")
#ManyToOne
[private Bookmarks bookmarkId;
and i have also changed the query to work
tring queryString = "SELECT b, sum(v.votedPoints) " +
"FROM Bookmarks b " +
"LEFT OUTER JOIN b.votesCollection v " +
"WHERE b.userId = 101 " +
"GROUP BY b.organizationId " +
"ORDER BY sum(v.votedPoints) asc ";
thanks for the help
May be you have some double-quotes " missing or which should be doubled in your HQL.
Illustration here.
Or you miss some simple quotes as illustrated there
The query seems to be invalid unless it's an artifact of formatting.
I think you meant this:
Select b, ...
to be:
Select b.organizationId, ...
??
I have the consistent set of jars because simple queries like this one
"SELECT b FROM table_name b WHERE b.userId = 102 "
are working. I have verified all double quotes and everything is alright.
My database is: mysql, and I use jpa to connect to it. I don't know what is causing the problem. Maybe this type of join, i don't know
Er, isnt your query trying to select b which is a table alias and thats not allowed as far as I know.
I'd probably guess that something is going wrong with your query, because the method HqlBaseParser fails to lookup is called recover(RecognitionException, Bitset). Perhaps this query fails for some reason the other simpler queries don't (and the NoSuchMethod exception is thrown when attempting to recover from that error).
java.lang.NoSuchMethodError: org.hibernate.hql.antlr.HqlBaseParser.recover(Lantlr/RecognitionException;Lantlr/collections/impl/BitSet;)V
Your query is still wrong. Maybe it works with your driver/db but it isn't standard SQL. You should be selecting b.* or b.organizationId.
Related
I am trying do something super simple but with Spring Repositories somethings is a bit hard. Basically I wanted to group by with DATE_FORMAT, example:
#Query("SELECT " +
" new users.bridge.models.dto.PerformanceDTO(sum(t.gl), sum(t.gl)) " +
"FROM " +
" Transaction t " +
"GROUP BY DATA_FORMATE(t.createdDate,'%Y-%m-%d')")
But it throws a syntax error. Is there a way to do that with spring repositories? I don't want to use nativeQuery=true flag, otherwise I can not use this syntax
new gara.users.bridge.models.dto.PerformanceDTO(sum(t.gl), sum(t.gl))
UPDATE:
The erros are:
all the java stack is quite big but:
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: asc near line 1, column 180 [SELECT new gara.users.bridge.models.dto.PerformanceDTO(sum(t.gl), sum(t.gl),t.createdDate) FROM gara.model.db.Transaction t GROUP BY DATE_FORMAT(t.createdDate,'%Y-%m-%d') asc]
If you specify nativeQuery=false (the default) you need to use valid JPQL.
JPQL doesn't know the function DATE_FORMAT but you can use the generic FUNCTION function which allows you to call arbitrary SQL functions.
So a group by clause like this should work: GROUP BY FUNCTION('DATA_FORMAT', t.createdDate,'%Y-%m-%d')
Just be aware that such queries aren't portable between databases.
but with Spring Repositories somethings is a bit hard.
You can always fall back on custom method implementations which shouldn't be much harder than implementing your repository yourself in the first place.
I'm currently having a little issue with JPA 2 and Typed Query.
I'm creating a search feature in my project using LIKE clause, however when I try to search for a string like "marina" it no works, it works only when I type "marin", even when exists in the database the name marina.
This is my code:
StringBuilder builder = new StringBuilder("select u from User u"
+ " where (u.login LIKE :regex OR u.fullname LIKE :regex)"
+ " AND (u.status <> :status)"
+ " order by u.fullname");
TypedQuery<User> query = jpaAPI.em().createQuery(builder.toString(),User.class);
query.setParameter("status", statusTypeDeleted());
query.setParameter("regex", "%"+regex+"%");
query.setFirstResult(init);
query.setMaxResults(end);
So, does anyone know where is the problem?
Ok. I solved this problem right now.
The problem is on this line:
query.setFirstResult(init);
The value I was passing to this method was 1 instead 0. How just exist only one entity with name "marina", the query result nothing, since the first result should be 0.
I have below name query
#NamedQuery(name="ScInstantTrack.getCustomerDetails",
query="select b.cardDetail.mstCustomer.customerId, last_day(b.endDate), " +
"LISTAGG(b.txnId,'|') WITHIN GROUP (ORDER BY b.endDate), " +
"count(b.txnId), sum(b.amount), sum(b.balanceAmt), sum(b.redemptionAmt) " +
"from ScInstantTrack b " +
"where b.cardNo = b.cardDetail.cardBarcode " +
"AND b.cardDetail.mstCustomer.customerId = :customerId " +
"and b.startDate <= trunc(:todayDate) " +
"and b.endDate >= trunc(:todayDate) " +
"and b.cardDetail.mstStatus.statusId = 3003 group by b.cardDetail.mstCustomer.customerId, last_day(b.endDate)")
When I am executing this query then getting below error :
unexpected token: WITHIN
I am using Oracle Database.
Why I am getting this error? How to solve this issue?
Try to use #NamedNativeQuery instead of #NamedQuery.
Also check this explanation of difference between them.
Basically you are using expressions that are exclusive in Oracle DB. In other words - you want to execute native query (query in native for Oracle DB language). Named queries use Java Persistence Query Language (HQL i.e.).
The error happen because LISTAGG is an oracle specific function.
That function is not avaliable in HQL and there is nothing you can use instead for HQL.
In order to get the result you have to use a SQLQuery wich perform native SQL queryes. This way You have to implement a version of thw query for each database, but it will work.
so tried to put that SQL code into my java-aplication:
SELECT DISTINCT
StRzImRo.Rohstoff, StRo.Bezeichnung,
CAST (SUM(BwLsImAt.Lieferungen * StRzImRo.Menge * StAt.PROD__REZEPTURGEWICHT / Coalesce(StRz.PARM__BEZUGSGROESSE,1)) AS NUMERIC (9,3)) Rohstoffverbrauch_Gesamt FROM BwLsImAt
JOIN StAt ON (StAt.IntRowId = BwLsImAt.Artikel)
JOIN StRz ON (StRz.IntRowId = StAt.PROD__REZEPTUR)
JOIN StRzImRo ON (StRzImRo.Master = StRz.IntRowId)
JOIN StRo ON (StRzImRo.Rohstoff = StRo.IntRowId)
WHERE StAt.IntRowId > 0
GROUP BY StRzImRo.Rohstoff, StRo.Bezeichnung
-- GROUP BY StRzImRo.Rohstoff, StRzImRo.Menge, StAt.PROD__REZEPTURGEWICHT, Coalesce(StRz.PARM__BEZUGSGROESSE,1)
The code is fully funcional and tested in IBSQL but not working in my java-application.
My app does work properly with other code. I get this error:
org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544569. Dynamic SQL Error
SQL error code = -104
Token unknown - line 1, column 266
ON
I would be very happy if someone could help me with this problem. Thanks!
P.S.: Sorry for my bad language, but i´m not a native speaker
The error suggests there is an ON in an unexpected place in your query, and as the query itself looks fine, my guess is the problem is with the way you construct the query in your Java application. There might be some whitespace missing in your query.
My guess is that you have something like
query = "SELECT * " +
"FROM table1" +
"JOIN table2 ON " //.....
The missing whitespace will make the SQL:
SELECT * FROM table1JOIN table2 ON ....
For the parser, this is perfectly valid until it encounters the ON token, which triggers the error. Eg the parser identifies it is a SELECT with * (all) columns from table1JOIN with alias table2. During parsing the server doesn't check if the table actually exists, so it doesn't trip over the fact that table1JOIN doesn't exist. That is checked after parsing is successfully completed.
I've got a problem with the following code, written in play (1.2.4):
List<MSprache> sprachen = MSprache.find("active = ?", true).fetch();
List<MFieldDscr> textey = MFieldDscr.find("sprache IN", sprachen).fetch();
And if I execute a test, which tests this part of code, the following Error displays:
A java.lang.IllegalArgumentException has been caught, org.hibernate.hql.ast.QuerySyntaxException: unexpected token: null near line 1, column 48 [from models.Sprache.MFieldDscr where sprache IN]
I don't understand where the mistake is.
I'm not so sure about what you're trying to achieve,
but I think this is what you want:
String jpql = "FROM MFieldDescr fd WHERE fd.sprache "
+ "IN ( SELECT s FROM MSprache s WHERE s.active = ? ) ";
List<MFieldDscr> textey = MFieldDescr.find( jpql, true ).fetch();
This will find all the MFieldDescr entities which have a MSprache with active set to true.
The language used to query entities is JPQL by the way, in case you want to learn more about it.
Here are some useful links:
JPQL In Expressions
JPQL Subqueries