I have a rather complex query here, where I also need to return the total of available result sets in addition to a limited result set.
There is the SQL_CALC_FOUND_ROWS option in MySQL, which allows to return that number in a subsequent query by using an interceptor. I have already implemented this in a similar project, by using a hibernate with a native query and an interceptor and it worked fine.
However in this case, there already is this complex JPA Criteria query and I would be more than happy if I could add that mysql option to the criteria query, but couldn't find a way to do this so far.
Below are some details about how the entityManager and Criteria is set up
#Stateless
class Dao{
#PersistenceContext(unitName = "persistenceName")
private EntityManager entityManager;
#TransactionAttribute(TransactionAttributeType.SUPPORTS)
public List<Entity> find(String someParam) {
CriteriaBuilder cb = this.entityManager.getCriteriaBuilder();
CriteriaQuery<Entity> cq = cb.createQuery(Entity.class);
Root<Entity> root = cq.from(Entity.class);
// some dummy predicate here
cq.where(predicates);
TypedQuery<Entity> query = this.entityManager.createQuery(cq);
// limit query
query.setFirstResult(100);
query.setMaxResults(10);
return query.getResultList();
}
}
Any ideas how to add the SQL_CALC_FOUND_ROWS option?
This thing runs in Glassfish 3 with Hibernate 3.5
I had the same issue when using eclipselink, and this fixed it for me:
query.setHint("eclipselink.sql.hint", "SQL_CALC_FOUND_ROWS");
The eclipselink.sql.hint flag instructs the string to be added immediately after the first word in the query, in this case SELECT. There may be an equivalent for Hibernate.
Related
SELECT p.patient_id as patientId,p.user_id as userId,u.first_name as first_name
I want this query to run in my junit test case.I know hsql does not support this and i need a solution for this.pls help
This is a MySQL query and therefore if you want to run it as is, it will have to be run as a native query. You can use code similar to the following:
String query = "SELECT p.patient_id as patientId ...";
Query q = em.createNativeQuery(query);
List<Object[]> rows = q.getResultList();
for (Object[] r: rows) {
// process each row as your unit test requires
}
If you need to use a parameterized native query, then you will have to use positional parameters. Refer to the following Stack Overflow question for an example:
How to create a native query with named parameters?
I wanted to get records of Patient(POJO class) who's contact number is not null. So, I referred this post.
In the answer two ways are specified
SELECT *
FROM table
WHERE YourColumn IS NOT NULL;
SELECT *
FROM table
WHERE NOT (YourColumn <=> NULL);
From above I wrote below hql which runs successfully
from Patient p where p.contactNo is not null
But, for 2nd type of hql
from Patient p where not (p.contactNo <=> null)
throws Exception
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: >
How can I use mysql null safe equality operator <=> in HQL?
HQL is a different language than MySQL. MySQL operators are not necessarily available in HQL.
This being said, you can given Hibernate MySQL queries (provided your database is MySQL):
Query query = entityMangager.createNativeQuery("Some MySQL code");
List results = query.getResultList();
EntityManager is an interface from the Java Persistence API. Hibernate has a tutorial about using the JPA, but here are the main points:
In order to have an entity manager, you need META-INF/persistence.xml file in your classpath. Then, inside a Java EE container, you get an instance of this interface with the #PersistenceContext annotation:
#PersistenceContext(unitName = "persistenceUnit")
private EntityManager em;
Outside a Java EE container, you can get one with the Persistence class:
EntityManagerFactory factory = Persistence.createEntityManagerFactory("persistenceUnit");
EntityManager em = factory.createEntityManager();
In both case, "persistenceUnit" must be the name of a persistence unit defined in your persistence.xml file.
I have a database table alert and am using Hibernate.I am using mySQL.
I want to update all columns of the database.
The table name is alert where as the mapping class of the table is Alert.
Using SQLQUERY:
session.beginTransaction();
session.createSQLQuery("update alert set retryCount=3");
session.getTransaction().commit();
session.close();
is not working.
Using HQL using dynaming update attribute
Query query=session.createQuery("from Alert");
for(int i=0;i<query.list().size();i++){
Alert alert=(Alert)query.list().get(i);
alert.setretryCount(3);
session.update(alert);
}
session.getTransaction().commit();
is working
Though the second one is working I think it will take much more time than a normal sql query.Is it so?Whats the best way to update a set of columns of all rows while using hibernate.
Hi ! Have you tried this ?
session.beginTransaction();
String queryString = "update Alert a set a.retryCount=3"
Query query = session.createQuery(queryString);
session.executeUpdate(query);
session.close();
This is on the hibernate official documentation. This is an HQL request using entities as objects and not as SQL tables. I think it's better to do it this way since you don't need to care about your database model.
Could you give us the displayed stacktrace for the non-working method ?
I'm using Hibernate but doing a simple SQLQuery, so I think this boils down to a basic JDBC question. My production app runs on MySQL but my test cases use an in memory HSQLDB. I find that a SELECT COUNT operation returns BigInteger from MySQL but Long from HSQLDB.
MySQL 5.5.22
HSQLDB 2.2.5
The code I've come up with is:
SQLQuery tq = session.createSQLQuery(
"SELECT COUNT(*) AS count FROM calendar_month WHERE date = :date");
tq.setDate("date", eachDate);
Object countobj = tq.list().get(0);
int count = (countobj instanceof BigInteger) ?
((BigInteger)countobj).intValue() : ((Long)countobj).intValue();
This problem of the return type negates answers to other SO questions such as getting count(*) using createSQLQuery in hibernate? where the advice is to use setResultTransformer to map the return value into a bean. The bean must have a type of either BigInteger or Long, and fails if the type is not correct.
I'm reluctant to use a cast operator on the 'COUNT(*) AS count' portion of my SQL for fear of database interoperability. I realise I'm already using createSQLQuery so I'm already stepping outside the bounds of Hibernates attempts at database neutrality, but having had trouble before with the differences between MySQL and HSQLDB in terms of database constraints
Any advice?
I don't known a clear solution for this problem, but I will suggest you to use H2 database for your tests.
H2 database has a feature that you can connect using a compatibility mode to several different databases.
For example to use MySQL mode you connect to the database using this jdbc:h2:~/test;MODE=MySQL URL.
You can downcast to Number and then call the intValue() method. E.g.
SQLQuery tq = session.createSQLQuery("SELECT COUNT(*) AS count FROM calendar_month WHERE date = :date");
tq.setDate("date", eachDate);
Object countobj = tq.list().get(0);
int count = ((Number) countobj).intValue();
Two ideas:
You can get result value as String and then parse it to Long or BigInteger
Do not use COUNT(*) AS count FROM ..., better use something like COUNT(*) AS cnt ... but in your example code you do not use name of result column but it index, so you can use simply COUNT(*) FROM ...
I have a sql query like this
select column from table where path = left('INPUTSTRING', length(path));
and trying to accomplish it in hql like this,
return session.createQuery("from Table where Path = left(:input, length(Path))").
query.setParameter("input", inputPath).
.list();
and getting an error like this
Caused by: org.hibernate.hql.ast.QuerySyntaxException: unexpected token: left near line 1
how to get this done? What is the corresponding string function in hql? Is there a solution for this using criteria query apis?
Yes, left() is not supported by the MySQLDialect. See the list of HQL supported functions on API docs.
Now you have left with 2 options.
Use session.createSQLQuery() method.
Create Your own Dialect class by extending the MySQLDialect and register the function there. This is told at hibernate forum here explained well in a blog post here.
I'm not sure if HQL does this for you , but you can use IQuery/session.CreateSQLQuery() to use a raw SQL query to populate a mapped entity. I've never used it for substrings, but have used it for aggregate functions. Check chapter 13 of the NHibernate docs and see if that does it for you. You can check the query substitution available in Nhibernate - here