I am familiar with Java but really new with ORM and Hibernate.
I am using the following query to get the resultset of all columns of a table in hibernate.
(List<Neighborhood>)session.createSQLQuery("SELECT * FROM Neighborhood").addEntity(Neighborhood.class).list();
I want to get only two specific column from this table. I looked up over the internet but not able to find the solution which can be used as a modification of above statement.
I tried the below query but getting - SQLGrammarException: could not extract ResultSet
(List<Neighborhood>)session.createSQLQuery("SELECT neighborhoodName,educationYouth FROM Neighborhood").addEntity(Neighborhood.class).list();
Edit:
Two more attempted queries after #scaryWombat's suggestion. Both give the same exception
First
List list = session.createSQLQuery("SELECT neighborhoodName,educationYouth FROM Neighborhood").list();
Second
String sql = "SELECT neighborhoodName,educationYouth FROM Neighborhood";
SQLQuery query = session.createSQLQuery(sql);
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List results = query.list();
Edit2:
After #Tehmina's solution, I am getting one error - java.sql.SQLException: Column 'educationYouth' not found because educationYouth is an object of class name "EducationYouth".
In the Neighborhood table there is no column with name educationYouth but all the column from EducationYouth class.
Try this
(List<Neighborhood>)session.createSQLQuery("SELECT * FROM Neighborhood").list();
To avoid the overhead of using ResultSetMetadata, or simply to be more explicit in what is returned, one can use addScalar():
(List<Neighborhood>)session.createSQLQuery("SELECT * FROM Neighborhood").addScalar("neighborhoodName", Hibernate.STRING).addScalar("educationYouth", Hibernate.STRING);
Or try this
Hibernate automatically converts the data into appropriate type. The automatic conversion does not work in all cases and in that case we have an overloaded version of addScalar():
SQLQuery q = session.createSQLQuery("SELECT * FROM Neighborhood");
q.addScalar("neighborhoodName");
q.addScalar("educationYouth");
List<Object[]> rows = q.list();
for (Object[] row : rows) {
System.out.println(row[0] + " " + row[1] );
Don't forget to check in the hibernate config file
<!--hibernate.cfg.xml -->
<property name="show_sql">true</property>
I hope it would resolve your error.
Related
I am absolutly new in Hibernate and I have the following problem.
I have this standard SQL query:
SELECT count(*)
FROM TID003_ANAGEDIFICIO anagraficaEdificio
INNER JOIN TID002_CANDIDATURA candidatura
ON (candidatura.PRG_PAR = anagraficaEdificio.PRG_PAR AND candidatura.PRG_CAN = anagraficaEdificio.PRG_CAN)
INNER JOIN TID001_ANAGPARTECIPA anagPartecipa ON(anagPartecipa.PRG_PAR = candidatura.PRG_PAR)
INNER JOIN anagrafiche.TPG1029_PROVNUOIST provNuovIst ON (provNuovIst.COD_PRV_NIS = anagPartecipa.COD_PRV_NIS)
WHERE anagraficaEdificio.FLG_GRA = 1 AND provNuovIst.COD_REG = "SI";
This works fine and return an integer number.
The important thing to know is that in this query the only
parameter that can change (inserted by the user in the frontend of a webappplication) is the last one (this one: provNuovIst.COD_REG = "SI").
So, the application on which I am working use Hibernate and the requirement say that I have to implement this query using Hibernate Native SQL, I have found this tutorial:
http://www.tutorialspoint.com/hibernate/hibernate_native_sql.htm
that show this example:
String sql = "SELECT * FROM EMPLOYEE WHERE id = :employee_id";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Employee.class);
query.setParameter("employee_id", 10);
List results = query.list();
that, from what I have understand (correct me if I am doing wrong assertion), involves the use of an Employee model class. So th prvious query first define the query (using the :param_name syntax for the parameter), then create an SQLQuery Hibernate object, add the class used for the result, set the previous parameter neam and finally obtain a List (that I think Hibernate create as something like an ArrayList) with the retrieved object.
My problem is that I simply I have to obtain an integer value (because I have a SELECT count(*), so I will obtain an integer value and not a set of rows).
So how can I correctly use the Hibernate Native SQL to implement my SQL query into my Hibernate repository class?
Use SQLQuery.uniqueResult to retrieve a single value from the query:
String sql = "SELECT count(*) ...";
SQLQuery query = session.createSQLQuery(sql);
// set parameters...
int count = ((Number)query.uniqueResult()).intValue();
I need to create a temporary table with hibernate and then insert data from a list into this table. here is what I mean :
String hql = "create temporary table temp (id int)";
session.createQuery(hql);
and inside this for loop i insert the data from a list into table 'temp' :
for(Example example : examples) {
hql = "insert into temp (" + example.getId() + ")";
query = session.createQuery(hql);
query.executeUpdate();
}
when i fill the table with the valuse from examples (which is a list), then i can use this table for another query. create and insert to this table has to be done automatically in my code and cant do it in database manually because the list 'examples' is made is the code.
this is what i think about the code, but it does not work. can anybody tell me how i can do this in correct way? thanks.
I don't think Hibernate Query Language manage "create" operation. Probably you need to run a native query in using createNativeQuery if you are using EntityManager or createSQLQuery if you are using Hibernate Session:
String hql = "create temporary table temp (id int)";
session.createSQLQuery(hql).executeUpdate();
I'm having trouble when trying to run the following query against an in memory H2 (version 1.4.181) table:
Object result = hibernateSession
.createSQLQuery("show columns from :myTable")
.setString("myTable", "some_table")
.list();
This query causes the following exception:
Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "SHOW COLUMNS FROM ?[*] "; expected "identifier"; SQL statement: show columns from ? [42001-181]
...
...
...
I had done some debbuging and I found that during parse of query, the character "?" is tested to check if it is a valid identififer and it fails, causing the rise of exception (class org.h2.command.Parser, line 3027):
//currentToken is "?" at this point
if (currentTokenType != IDENTIFIER) {
throw DbException.getSyntaxError(sqlCommand, parseIndex,
"identifier");
}
I think it is a bug. What you think?
No, it is quite normal. Hibernate could not possibly make a PreparedStatement of it.
Standard JDBC has many possibilities to query schemata and such, in a database vendor independant way.
DatabaseMetaData dbMeta = connection.getMetaData();
Then getColumns can be used to receive a ResultSet of miscellaneous information.
You can try creating the required query instead of setting table name as named-parameter which won't work.
String sqlQuery = "show columns from " + tableName;
Class<?> entity = Class.forName(entityName);
session.createSQLQuery(sqlQuery);
Get the metadata information & then can retrieve required details from it.
String[] properties =
sessionFactory.getClassMetadata(entityClass).getPropertyNames();
There are several other methods available to get meta information, can refer ClassMetaData
[I haven't checked Criteria API, will update if found anything relevant, you can try it]
I want to use spring-batch for retrieving and processing data from a postgres db.
I have a working SQL statement that would give me the full result set (about 400k entries):
private static final String QUERY = "SELECT * FROM MyDataTable ";
Now I want to use the JpaPagingItemReader so that the data is fetched (and written elsewhere) in chunks:
JpaPagingItemReader<MyEntity> reader = new JpaPagingItemReader<>();
reader.setEntityManagerFactory(emf);
reader.setQueryString(QUERY);
But it does not work:
[] 2014-09-17 16:31:58,234 ERROR : QuerySyntaxException: unexpected token: * near line 1, column 8 [SELECT * FROM my_data_table]
I also tried SELECT FROM MyDataTable and SELECT m FROM MyDataTable m without the star. Same result.
So, how can I execute that hql query with spring-batch?
By the way: the query works fine in a sql editor like pgAdmin.
SELECT m FROM MyDataTable m is almost correct (it is valid JPQL query as long as you have entity calles MyDataTable). So, it seems that you don't have entity class named MyDataTable.
As JpaPagingItemReader#setQueryString(String) accepts JPQL queries you should make sure that you have entity class for this table and then you should use its name instead MyDataTable.
By the way - for HQL queries there's HibernatePagingItemReader.
I'm building a select that has to get me all distinct values from a table.
The sql I would normally write would look like this: "SELECT DISTINCT ARTIST FROM MUSICLIB"
However, ebean is generating the following: "SELECT DISTINCT ID, ARTIST FROM MUSICLIB"
The finder is as such:
find.select("artist").setDistinct(true).findList();
I've found that ebean is generating this ID on every single query, no matter what options I set.
How do I accomplish what I'm looking for?
You can't do that, Ebean for objects mapping requires ID field, and if you won't include it you'll get some mysterious exceptions.
Instead you can query DB without mapping and then write your SQL statement yourself:
SqlQuery sqlQuery = Ebean.createSqlQuery("SELECT DISTINCT artist FROM musiclib");
List<SqlRow> rows = sqlQuery.findList();
for (SqlRow row : rows) {
debug("I got one: " + row.getString("artist"));
}
Of course if artist is a relation, you need to perform additional query using list of found IDs with in(...) expression.