I've recently started trying to use Hibernate, but am doing so in Netbeans. This has left me having to use this example project to try and get me up and running.
Unfortunately, at the step "Enumerating Film Titles and Retrieving Actors Using an HQL Query" my HQL queries do not give results and instead fail, with the exception:
org.hibernate.exception.SQLGrammarException: could not execute query
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from limit 100' at line 1
It seems that the HQL isn't generating proper MySQL statements but I can't seem to see why, as I've followed the example to the letter thus far.
I am attempting to connect to a local MySQL database named 'sakila', with the following details:
jdbc:mysql://localhost:3306/sakila
which seems to work correctly as I am able to browse the tables from within Netbeans no problem.
My hibernate.cfg.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/sakila</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.show_sql">true</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>
<mapping resource="dvdrental/Language.hbm.xml"/>
<mapping resource="dvdrental/FilmActor.hbm.xml"/>
<mapping resource="dvdrental/FilmCategory.hbm.xml"/>
<mapping resource="dvdrental/Category.hbm.xml"/>
<mapping resource="dvdrental/Film.hbm.xml"/>
<mapping resource="dvdrental/Actor.hbm.xml"/>
</session-factory>
</hibernate-configuration>
When I'm using the HQL Query window, the SQL it seems to generate only ever says 'select from ' which is obviously wrong, but I can't see why this is being caused?
Edit 1: The HQL Query tab showing my input
Completely stupid reason- I hadn't even thought about the fact I hadn't built the project, so the example code from the bottom of the example ran properly (cause it came pre-compiled). Works no problem now.
I think the main cause of the error is as stated earlier from User, the U in User should be uppercase/capitalized as hibernate uses the POJO. I tried recompiling the code and it works correctly for the sample Swing application: https://netbeans.org/kb/docs/java/hibernate-java-se.html.
However the HQL Query editor still gives this error. It is strange but seems like this editor is not reliable.
The error message 'from limit 100' from your posted exception tells me, that you forgot to add Film after from. Please provide the HQL query that throws the exception.
BTW: the examples in the example project are bad practice. You should never use inline arguments in HQL queries:
from Film as film where film.filmId between '"+startID+"' and '"+endID+"'
You should use query parameters:
Query q = session.createQuery("from Film as film where film.filmId between :startID and :endID");
q.setParameter("startID", startID);
q.setParameter("endID", endID);
When I'm using the HQL Query window, the SQL it seems to generate only ever says 'select from ' which is obviously wrong, but I can't see why this is being caused?
A simple
from Film
is valid HQL and should work. Could you try without the following line:
<property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>
Not sure this will solve the problem but there is no reason to use the "old" parser anyway.
That replaces the problem with a new one I'm afraid. Now the SQL tab of the HQL pane reports 'Invalid Query', and if I run the query I get org.hibernate.hql.ast.QuerySyntaxException. Any further pointers?
As I said, I was not sure this would solve the problem. What I would do is write a "simple" JUnit test to validate the setup is working. But an obvious bug like this in NetBeans HQL Query window is unlikely, IMO.
Completely stupid reason- I hadn't even thought about the fact I hadn't built the project, so the example code from the bottom of the example ran properly (cause it came pre-compiled). Works no problem now.
I experienced exactly the same problem but I think your stated solution is not correct. Even your project is not compiled HQL will show you results.
One should be careful of Table name in hibernate.cfg.xml file
as it should be same in query (case sensitive) also for example in your case it has table name as "Actor" so
from Actor will work, not from actor
Related
I need to map in Java with hibernate a table in sqlserver that has spaces in the column names.
I use Sqlserver 2008 jre7 com.microsoft.sqlserver.sqljdbc4 with Hibernate 3.3.2
I found a lot of similar questions in different forums but none of the solutions I read worked.
I tried using the backtick
<property name="nameSpaces" type="string" >
<column name="`Name with spaces`" not-null="false" />
</property>
this is the error
com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near '`'.
I also tried to use the [] brakets but hibernate converted it in ` again.
<column name="[Name with spaces]" not-null="false" />
com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near '`'.
Finally I also tried both of them
<column name="`[Name with spaces]`" not-null="false" />
or
without success.
Can someone help me? Is there any hibernate configuration I can change to work with these column names.
Thanks
The answer (by BilalDja) is hidden above in a comment. I found his answer helpful so I thought I would add the answer here for others with the same problem.
This issue is hard to debug, I had to dig really deep into the hibernate and jdbc code to finally find the "real" SQL statement that is created to get data from the database. I then copied its value and ran it manually on my SQL Server database. Straight away the syntax error was obvious and sure enough it was cause by a space in a column name.
To fix this I just escaped the double quotes around the problematic column name as explained in BilalDja's comments and expanded slightly here...
#Column(name = "\"Column name\"")
private String variableColumnWillMapTo;
That's it, problem solved, no more syntax error.
i need to translate this SQL expressioninto Hibernate using Criteria
select id,field1,field2,count(*) from my_table
group by field1,field2 having count(*)>1;
here is my code so far.
final Session session = ......
ProjectionList projectionList = (ProjectionList)emptyProjection();
projectionList.add(Projections.property("id"),"id");
projectionList.add(Projections.groupProperty("codeI"));
projectionList.add(Projections.groupProperty("codeII"));
projectionList.add(Projections.sqlGroupProjection("count(*)","having count(*)>1",new String[]{},new Type[]{StandardBasicTypes.INTEGER}));
final Criteria criteria = session.createCriteria(MyClass.class).setProjection(projectionList).setResultTransformer(transformer(MyClass.class));
return new ArrayList<MyClass>(criteria.list());
my problem is
the criteria is generating this SQL.
group by
this_.FIELD1,
this_.FIELD2,
having
count(*)>1
as you can see the second group by is followed by a COMMA this_.FIELD2, and mySQL is throwing SyntaxError
UPDATE
here is my hibernate.cfg
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
and we are using mysql 5.5.29 and HIBERNATE 4.2.3
i hope somebody give a tip.
best regards..
Hibernate does not support a having clause in the Criteria API. Your code is tantalizing close to the SQL you want, but what you've actually specified is just another group by condition, hence the comma. Here is a feature request from forever ago: https://hibernate.atlassian.net/browse/HHH-1043.
If you must use a criteria, then you can use a subquery which will end up being slow. HQL does support the clause so you could do it that way.
More discussion and examples: Hibernate Criteria API - HAVING clause work arounds.
I have a sample application which loads 2 records ro database and then fetches all the records from DB and prints info from every record.
My problem is follow: when I run program, it fetches only records which inserted on this running, but not before, Also, when I'm opening DB with SQirrel, there is no such database.
Here is my Hibernate config:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:hibertest</property>
<property name="connection.username">sk</property>
<property name="connection.password">0000</property>
<property name="show_sql">true</property>
<property name="current_session_context_class">thread</property>
<property name="hbm2ddl.auto">update</property>
<mapping class="models.Work" />
</session-factory>
</hibernate-configuration>
What I'm doing wrong?
I am not experienced with HSQLDB but try the following URL:
<property name="connection.url">jdbc:hsqldb:file:hibertest;shutdown=true</property>
See: Connection URL documentation.
I believe the default configuration of hsqldb is to not save data on disk for created tables. Please check the hsqldb documentation for how to change this behavior and make tables persistent.
http://hsqldb.org/doc/guide/guide.html#sgc_persist_tables
All the provided answers didn't help me at all.
Currently I use HSQLDB-2.3.2 and hibernate-core-3.5.6 with annotations-3.2.0
In addition to the answer of Tomasz, I needed to manually edit the database script file setting this:
SET WRITE_DELAY 0
You can persist the Data using the HSQL by doing the following,
1.
Connection c = DriverManager.getConnection("jdbc:hsqldb:file:/opt/db/testdb", "SA", "");
"/opt/db/testdb" here is the DB location in the disk.
2. CREATE **TEXT** TABLE <tablename> (<column definition> [<constraint definition>])
3. Assign the source for the Table SET TABLE mytable SOURCE "myfile;fs=|"
Ref: http://hsqldb.org/doc/2.0/guide/texttables-chapt.html
My Github Repository shows the sample https://github.com/Ayyamperumal/HSQL/tree/master/SampleHSQLdb
you can use "Database Development" perspective from Eclipse to see the data. (Supply hsql jar as the driver) Or Execute org.hsqldb.util.DatabaseManager from the hsqldb-*.jar to get the GUI for seeing the data.
I have just updated to Hibernate 3.6.5.Final from 3.3.0.GA and have run into a problem with a SQL formula call on an XML mapped property:
<property
name="endDate"
type="java.util.Date"
formula="TIMESTAMPADD(SECOND, (quantity*60*60), transactionDate)"
/>
I have changed nothing in the *.xml.hbm nor have I changed the database design. Where previously my endDate was nicely calculated I now get a MySQLSyntaxErrorException:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'this_.SECOND,(this_.quantity*60*60),this_.transactionDate) as formula0_0_ from t' at line 1
The problem is pretty obvious in that the this_.SECOND should be SECOND. It seems to me that Hibernate recognizes the TIMESTAMPADD as a formula but not the SECOND as a static passed parameter and thinks it thus must be a column in the table. I am unsure how to tell hibernate it should use SECOND as is.
I've tried registerFunction and registerKeyword on my Dialect but without any luck as these seem related to HQL function definitions and not native SQL which is used here in the formula.
Could anyone point me in the right direction or tell me what Hibernate does different between these versions and how I can fix it?
I just upgraded to Hibernate 4.1.2 and this same problem started coming back. The solution of [SECOND] no longer works and I had to register the keyword in my own custom Dialect. Like:
public class ExtendedMySQL5InnoDBDialect extends MySQL5InnoDBDialect {
public ExtendedMySQL5InnoDBDialect() {
super();
//make sure to register it in lowercase as uppercase does not work (took me 4 hours to realize)
registerKeyword("second");
}
}
I had the same type of problem in Sql Server - a similar solution might work. .
Here is what I found. .
https://forum.hibernate.org/viewtopic.php?p=2427791
So, try putting quotes around SECOND
<property
name="endDate"
type="java.util.Date"
formula="TIMESTAMPADD("SECOND", (quantity*60*60), transactionDate)"
/>
I am actually not sure how you would escape double quotes in this xml attribute, but I would try " first and if that doesn't work \"
I am writing a query but it always says "No matching index found". I don't know why. My code is as below:
Query query = pm.newQuery(Classified.class);
query.setFilter("emp_Id == emp");
query.setOrdering("upload_date desc");
query.declareParameters("String emp");
List<Classified> results = (List<Classified>)query.execute(session.getAttribute("emp_Id").toString());
<?xml version="1.0" encoding="utf-8"?>
<datastore-indexes autoGenerate="true">
<datastore-index kind="Classified" ancestor="false">
<property name="emp_Id" direction="asc" />
<property name="category" direction="asc" />
<property name="upload_date" direction="desc" />
</datastore-index>
</datastore-indexes>
I have added the above index, but it did not help.
I believe you need to configure a Datastore Index. There's probably one already generated for you in Eclipse at WEB-INF/appengine-generated/datastore-indexes-auto.xml that you just need to copy to WEB-INF/datastore-indexes.xml and deploy again.
Because this needs to be somewhere on the internet...
I kicked myself when I found this out
The error is you do not have a index matching what the query would like to perform. You can have multiple indexes for each entity.
In the Logcat, error, it will tell you exactly what index to set and what order the elements need to be.
ie, if the error says it wants (it wont be nicely formatted):
<datastore-index kind="Classified" ancestor="false">
<property name="category" direction="desc" />
<property name="upload_date" direction="desc" />
</datastore-index>
then Project -> war -> WEB-INF -> appengine-generated -> datastore-indexes-auto.xml and add exactly that. Then, redeploy the project.
Next go into your Google Cloud Console and look at Datastore -> indexes. It should say that the index is being prepared (This goes quicker if you can kill all apps connected and shut down the instance in the console).
Once this has moved into the list of other indexes, rerun the your application and it wont error out with regards to the index anymore.
Go get it Gentlemen/Ladies
The index you define must hold all possible results in the order they will be returned. Your query asks for a particular emp_Id, ordered by upload_date, but your index is ordered primarily by category.
Try removing the category line from your index definition, or swapping the order of category and upload_date, to make upload_date the primary sort order for the index. If another part of your code relies on the category line, you may have to make two separate indices (which incurs some computational cost).
Edit: see comment below by Nick Johnson re. extra parameters.
I am running into this issue at the moment when doing a single property query such as:
const query = datastore
.createQuery('Emailing_dev')
.filter('status', '=', 'Scheduled')
In my case, I should not be getting any errors, however I get Error 9: No matching index found.
If I defined the single property index twice in the yaml, it works:
indexes:
- kind: Emailing_dev
properties:
- name: status
- name: status
but this for sure must be a bug..!!