#117 improved GroupBy handling

This commit is contained in:
Timo Westkämper 2012-03-23 23:31:51 +02:00
parent f4641020fc
commit b4863a78f3
3 changed files with 75 additions and 58 deletions

View File

@ -40,8 +40,10 @@ import com.mysema.query.SearchResults;
import com.mysema.query.jpa.HQLTemplates;
import com.mysema.query.jpa.JPQLQueryBase;
import com.mysema.query.jpa.JPQLTemplates;
import com.mysema.query.jpa.hibernate.FactoryExpressionTransformer;
import com.mysema.query.types.Expression;
import com.mysema.query.types.FactoryExpression;
import com.mysema.query.types.FactoryExpressionUtils;
/**
* Abstract base class for JPA API based implementations of the JPQLQuery interface
@ -157,34 +159,39 @@ public abstract class AbstractJPAQuery<Q extends AbstractJPAQuery<Q>> extends JP
// set transformer, if necessary and possible
List<? extends Expression<?>> projection = getMetadata().getProjection();
if (projection.size() == 1 && !forCount) {
Expression<?> expr = projection.get(0);
if (expr instanceof FactoryExpression<?>) {
String transformation = null;
if (hibernateQueryClass != null && hibernateQueryClass.isInstance(query)) {
transformation = "com.mysema.query.jpa.impl.HibernateQueryTransformation";
FactoryExpression<?> wrapped = projection.size() > 1 ? FactoryExpressionUtils.wrap(projection) : null;
if (!forCount && ((projection.size() == 1 && projection.get(0) instanceof FactoryExpression) || wrapped != null)) {
Expression<?> expr = wrapped != null ? wrapped : projection.get(0);
String transformation = null;
if (hibernateQueryClass != null && hibernateQueryClass.isInstance(query)) {
transformation = "com.mysema.query.jpa.impl.HibernateQueryTransformation";
}
// else if (query.getClass().getName().startsWith("org.eclipse.persistence")) {
// transformation = "com.mysema.query.jpa.impl.EclipseLinkQueryTransformation";
// }
if (transformation != null) {
try {
Constructor<?> c = Class.forName(transformation).getConstructor(Query.class, FactoryExpression.class);
c.newInstance(query, expr);
} catch (NoSuchMethodException e) {
throw new QueryException(e);
} catch (ClassNotFoundException e) {
throw new QueryException(e);
} catch (InstantiationException e) {
throw new QueryException(e);
} catch (IllegalAccessException e) {
throw new QueryException(e);
} catch (InvocationTargetException e) {
throw new QueryException(e);
}
// else if (query.getClass().getName().startsWith("org.eclipse.persistence")) {
// transformation = "com.mysema.query.jpa.impl.EclipseLinkQueryTransformation";
// }
if (transformation != null) {
try {
Constructor<?> c = Class.forName(transformation).getConstructor(Query.class, FactoryExpression.class);
c.newInstance(query, expr);
} catch (NoSuchMethodException e) {
throw new QueryException(e);
} catch (ClassNotFoundException e) {
throw new QueryException(e);
} catch (InstantiationException e) {
throw new QueryException(e);
} catch (IllegalAccessException e) {
throw new QueryException(e);
} catch (InvocationTargetException e) {
throw new QueryException(e);
}
} else {
factoryExpressionUsed = true;
} else {
factoryExpressionUsed = true;
if (wrapped != null) {
getMetadata().clearProjection();
getMetadata().addProjection(wrapped);
}
}
}

View File

@ -118,36 +118,5 @@ public abstract class AbstractHibernateTest extends AbstractStandardTest{
rows.close();
}
@Test
public void GroupBy() {
QAuthor author = QAuthor.author;
QBook book = QBook.book;
for (int i = 0; i < 10; i++) {
Author a = new Author();
a.setName(String.valueOf(i));
session.save(a);
for (int j = 0; j < 2; j++) {
Book b = new Book();
b.setTitle(String.valueOf(i)+" "+String.valueOf(j));
b.setAuthor(a);
session.save(b);
}
}
Map<Long, List<Pair<Long, String>>> map = new HibernateQuery(session)
.from(author)
.join(author.books, book)
.transform(GroupBy
.groupBy(author.id)
.as(GroupBy.list(QPair.create(book.id, book.title))));
for (Entry<Long, List<Pair<Long, String>>> entry : map.entrySet()) {
System.out.println("author = " + entry.getKey());
for (Pair<Long,String> pair : entry.getValue()) {
System.out.println(" book = " + pair.getFirst() + "," + pair.getSecond());
}
}
}
}

View File

@ -28,7 +28,9 @@ import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.Map.Entry;
import org.junit.Before;
import org.junit.Ignore;
@ -38,16 +40,22 @@ import antlr.RecognitionException;
import antlr.TokenStreamException;
import com.mysema.commons.lang.Pair;
import com.mysema.query.group.GroupBy;
import com.mysema.query.group.QPair;
import com.mysema.query.jpa.JPQLGrammar;
import com.mysema.query.jpa.JPQLQuery;
import com.mysema.query.jpa.JPQLSubQuery;
import com.mysema.query.jpa.domain.Animal;
import com.mysema.query.jpa.domain.Author;
import com.mysema.query.jpa.domain.Book;
import com.mysema.query.jpa.domain.Cat;
import com.mysema.query.jpa.domain.DomesticCat;
import com.mysema.query.jpa.domain.Employee;
import com.mysema.query.jpa.domain.Foo;
import com.mysema.query.jpa.domain.JobFunction;
import com.mysema.query.jpa.domain.QAnimal;
import com.mysema.query.jpa.domain.QAuthor;
import com.mysema.query.jpa.domain.QBook;
import com.mysema.query.jpa.domain.QCat;
import com.mysema.query.jpa.domain.QEmployee;
import com.mysema.query.jpa.domain.QFoo;
@ -56,6 +64,7 @@ import com.mysema.query.jpa.domain.QUser;
import com.mysema.query.jpa.domain.Show;
import com.mysema.query.jpa.domain4.QBookMark;
import com.mysema.query.jpa.domain4.QBookVersion;
import com.mysema.query.jpa.hibernate.HibernateQuery;
import com.mysema.query.jpa.hibernate.HibernateSubQuery;
import com.mysema.query.types.ArrayConstructorExpression;
import com.mysema.query.types.Concatenation;
@ -686,4 +695,36 @@ public abstract class AbstractStandardTest {
assertTrue(strings.contains("b"));
}
@Test
public void GroupBy() {
QAuthor author = QAuthor.author;
QBook book = QBook.book;
for (int i = 0; i < 10; i++) {
Author a = new Author();
a.setName(String.valueOf(i));
save(a);
for (int j = 0; j < 2; j++) {
Book b = new Book();
b.setTitle(String.valueOf(i)+" "+String.valueOf(j));
b.setAuthor(a);
save(b);
}
}
Map<Long, List<Pair<Long, String>>> map = query()
.from(author)
.join(author.books, book)
.transform(GroupBy
.groupBy(author.id)
.as(GroupBy.list(QPair.create(book.id, book.title))));
for (Entry<Long, List<Pair<Long, String>>> entry : map.entrySet()) {
System.out.println("author = " + entry.getKey());
for (Pair<Long,String> pair : entry.getValue()) {
System.out.println(" book = " + pair.getFirst() + "," + pair.getSecond());
}
}
}
}