I need to get working a pagination with hibernate.
My first solution to don't wait for two querys to launch is to do it with threads:
Thread1.start();
Thread1.join();
ThreadCountQuery.start();
ThreadPagingQuery.start();
ThreadCountQuery.join(); --> Join mainThread to CountQuery
ThreadPagingQuery.join();--> Join mainThread to PagingQuery
Is to say, I've one main thread that waits until the countQueryThread and the PagingQueryThread terminates.
I think that if the countQuery is about 1second and the PagingQuery about 2 seconds, with this solution, I can get the results in 2 seconds, the slower process.
The problem is that I can do this with the Query Object, but not with criterias(I cannot replicate criterias)
Is there any other better solution?
I atach the code of the threads:
MainThread:
Code:
public class DefaultPageThread<T> implements Runnable {
private int pageNumber, pageSize;
protected enum Mode {CRITERIA,JPA,HIBERNATE};
private Mode tipoQuery;
private Criteria criteriaQuery,criteriaCountQuery;
private Query query,queryCount;
private javax.persistence.Query queryJPA,queryCountJPA;
private DefaultPage<T> page;
public int getPageNumber() {
return pageNumber;
}
public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public DefaultPageThread(){
}
public DefaultPageThread(Criteria criteriaQuery,Criteria criteriaCount){
this.tipoQuery = Mode.CRITERIA;
this.criteriaQuery = criteriaQuery;
this.criteriaCountQuery = criteriaCount;
}
public DefaultPageThread(Query query,Query queryCount){
this.tipoQuery = Mode.HIBERNATE;
this.query = query;
this.queryCount = queryCount;
}
public DefaultPageThread(javax.persistence.Query query,javax.persistence.Query queryCount){
this.tipoQuery = Mode.JPA;
this.queryJPA = query;
this.queryCountJPA = queryCount;
}
@Override
public void run() {
this.page = new DefaultPage<T>(this.getPageNumber(),this.getPageSize());
Thread queryCount = null;
Thread query = null;
QueryThread<T> queryThread = null;
QueryCountThread<T> queryCountThread = null;
switch(this.tipoQuery){
case CRITERIA:
queryThread = new QueryThread<T>(this.getCriteriaQuery());
queryCountThread = new QueryCountThread<T>(this.getCriteriaCountQuery());
break;
case JPA:
queryThread = new QueryThread<T>(this.getQueryJPA());
queryCountThread = new QueryCountThread<T>(this.getQueryCountJPA());
break;
case HIBERNATE:
queryThread = new QueryThread<T>(this.getQuery());
queryCountThread = new QueryCountThread<T>(this.getQueryCount());
break;
default:
break;
}
query = new Thread(queryThread);
queryCount = new Thread(queryCountThread);
queryCount.start();
query.start();
try {
query.join();
queryCount.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
this.page.elements = new ArrayList<T>();
this.page.elements.addAll(queryThread.getElements());
this.page.totalElements = queryCountThread.getTotalElements();
}
public static void main(String[] args) {
Thread t = new Thread(new DefaultPageThread());
t.start();
}
public Mode getTipoQuery() {
return tipoQuery;
}
public void setTipoQuery(Mode tipoQuery) {
this.tipoQuery = tipoQuery;
}
public Criteria getCriteriaQuery() {
return criteriaQuery;
}
public void setCriteriaQuery(Criteria criteriaQuery) {
this.criteriaQuery = criteriaQuery;
}
public Criteria getCriteriaCountQuery() {
return criteriaCountQuery;
}
public void setCriteriaCountQuery(Criteria criteriaCountQuery) {
this.criteriaCountQuery = criteriaCountQuery;
}
public Query getQuery() {
return query;
}
public void setQuery(Query query) {
this.query = query;
}
public Query getQueryCount() {
return queryCount;
}
public void setQueryCount(Query queryCount) {
this.queryCount = queryCount;
}
public javax.persistence.Query getQueryJPA() {
return queryJPA;
}
public void setQueryJPA(javax.persistence.Query queryJPA) {
this.queryJPA = queryJPA;
}
public javax.persistence.Query getQueryCountJPA() {
return queryCountJPA;
}
public void setQueryCountJPA(javax.persistence.Query queryCountJPA) {
this.queryCountJPA = queryCountJPA;
}
public DefaultPage<T> getPage() {
return page;
}
public void setPage(DefaultPage<T> page) {
this.page = page;
}
}
CountThreadCode:
public class QueryCountThread<T> implements Runnable {
private Mode tipoQueryCount;
private Criteria criteriaQueryCount;
private Query queryCount;
private javax.persistence.Query queryJPACount;
private int totalElements;
public QueryCountThread(){
}
public QueryCountThread(Criteria criteriaQuery){
this.tipoQueryCount = Mode.CRITERIA;
this.criteriaQueryCount = criteriaQuery;
}
public QueryCountThread(Query query){
this.tipoQueryCount = Mode.HIBERNATE;
this.queryCount = query;
}
public QueryCountThread(javax.persistence.Query query){
this.tipoQueryCount = Mode.JPA;
this.queryJPACount = query;
}
@Override
public void run() {
switch(this.tipoQueryCount){
case CRITERIA:
this.setTotalElements((Integer)this.getCriteriaQueryCount().uniqueResult());
break;
case JPA:
this.setTotalElements(((Long)this.getQueryJPACount().getSingleResult()).intValue());
break;
case HIBERNATE:
this.setTotalElements(((Long)this.getQueryCount().uniqueResult()).intValue());
break;
default:
break;
}
}
public Mode getTipoQueryCount() {
return tipoQueryCount;
}
public void setTipoQueryCount(Mode tipoQueryCount) {
this.tipoQueryCount = tipoQueryCount;
}
public Criteria getCriteriaQueryCount() {
return criteriaQueryCount;
}
public void setCriteriaQueryCount(Criteria criteriaQueryCount) {
this.criteriaQueryCount = criteriaQueryCount;
}
public Query getQueryCount() {
return queryCount;
}
public void setQueryCount(Query queryCount) {
this.queryCount = queryCount;
}
public javax.persistence.Query getQueryJPACount() {
return queryJPACount;
}
public void setQueryJPACount(javax.persistence.Query queryJPACount) {
this.queryJPACount = queryJPACount;
}
public int getTotalElements() {
return totalElements;
}
public void setTotalElements(int totalElements) {
this.totalElements = totalElements;
}
}
PagingThread:
Code:
public class QueryThread<T> implements Runnable {
private Mode tipoQuery;
private Criteria criteriaQuery;
private Query query;
private javax.persistence.Query queryJPA;
private Collection<T> elements;
public QueryThread(){
}
public QueryThread(Criteria criteriaQuery){
this.tipoQuery = Mode.CRITERIA;
this.criteriaQuery = criteriaQuery;
}
public QueryThread(Query query){
this.tipoQuery = Mode.HIBERNATE;
this.query = query;
}
public QueryThread(javax.persistence.Query query){
this.tipoQuery = Mode.JPA;
this.queryJPA = query;
}
@Override
public void run() {
this.elements = new ArrayList<T>();
//:TODO Poner HINT por first_rows
switch(this.tipoQuery){
case CRITERIA:
this.elements.addAll(this.getCriteriaQuery().list());
break;
case JPA:
this.elements.addAll(this.getQueryJPA().getResultList());
break;
case HIBERNATE:
System.out.println("ENTRAMOS EN LA QUERY DE HIBERNATE PARA OBTENER LOS ELEMENTOS");
this.elements.addAll(this.getQuery().list());
break;
default:
break;
}
}
public Collection<T> getElements() {
return elements;
}
public void setElements(Collection<T> elements) {
this.elements = elements;
}
public Mode getTipoQuery() {
return tipoQuery;
}
public void setTipoQuery(Mode tipoQuery) {
this.tipoQuery = tipoQuery;
}
public Criteria getCriteriaQuery() {
return criteriaQuery;
}
public void setCriteriaQuery(Criteria criteriaQuery) {
this.criteriaQuery = criteriaQuery;
}
public Query getQuery() {
return query;
}
public void setQuery(Query query) {
this.query = query;
}
public javax.persistence.Query getQueryJPA() {
return queryJPA;
}
public void setQueryJPA(javax.persistence.Query queryJPA) {
this.queryJPA = queryJPA;
}
}
Code that launch the main thread:
Code:
DefaultPage<T> sp = new DefaultPage<T>(pageNumber, pageSize);
query = query.setFirstResult(pageNumber * pageSize);
query = query.setMaxResults(pageSize);
query.setReadOnly(true);
countQuery.setReadOnly(true);
DefaultPageThread<T> defaultPageThread = new DefaultPageThread<T>(query,countQuery);
Thread thread = new Thread(defaultPageThread);
long start = System.currentTimeMillis();
thread.start();
try {
thread.join();
long end = System.currentTimeMillis();
System.out.println("Consulta THREAD HIBERNATE ...." + (end - start)
+ "ms");
sp = defaultPageThread.getPage();
sp.query = query;
sp.countQuery = countQuery;
sp.pageNumber = pageNumber;
sp.pageSize = pageSize;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}