small improvement in projection handling

This commit is contained in:
Timo Westkämper 2011-11-16 13:53:55 +02:00
parent ddf71006da
commit 235ef3648c
2 changed files with 41 additions and 21 deletions

View File

@ -363,36 +363,22 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
return configuration;
}
@SuppressWarnings("unchecked")
@Override
public CloseableIterator<Object[]> iterate(Expression<?>[] args) {
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof RelationalPath) {
args[i] = wrap((RelationalPath)args[i]);
}
}
queryMixin.addToProjection(args);
return iterateMultiple(queryMixin.getMetadata());
}
@SuppressWarnings("unchecked")
@Override
public <RT> CloseableIterator<RT> iterate(Expression<RT> expr) {
if (expr instanceof RelationalPath<?>) {
try{
if (expr.getType().equals(expr.getClass())) {
throw new IllegalArgumentException("RelationalPath based projection can only be used with generated Bean types");
}
Map<String,Expression<?>> bindings = new HashMap<String,Expression<?>>();
for (Field field : expr.getClass().getDeclaredFields()) {
if (Expression.class.isAssignableFrom(field.getType()) && !Modifier.isStatic(field.getModifiers())) {
field.setAccessible(true);
Expression<?> column = (Expression<?>) field.get(expr);
bindings.put(field.getName(), column);
}
}
if (bindings.isEmpty()) {
throw new IllegalArgumentException("No bindings could be derived from " + expr);
}
QBean<RT> bean = new QBean(expr.getType(), bindings);
return iterate(bean);
}catch(IllegalAccessException e) {
throw new QueryException(e);
}
return iterate(wrap((RelationalPath<RT>)expr));
} else {
expr = queryMixin.convert(expr);
queryMixin.addToProjection(expr);
@ -400,6 +386,29 @@ public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends
}
}
@SuppressWarnings("unchecked")
protected <RT> QBean<RT> wrap(RelationalPath<RT> expr) {
try{
if (expr.getType().equals(expr.getClass())) {
throw new IllegalArgumentException("RelationalPath based projection can only be used with generated Bean types");
}
Map<String,Expression<?>> bindings = new HashMap<String,Expression<?>>();
for (Field field : expr.getClass().getDeclaredFields()) {
if (Expression.class.isAssignableFrom(field.getType()) && !Modifier.isStatic(field.getModifiers())) {
field.setAccessible(true);
Expression<?> column = (Expression<?>) field.get(expr);
bindings.put(field.getName(), column);
}
}
if (bindings.isEmpty()) {
throw new IllegalArgumentException("No bindings could be derived from " + expr);
}
return new QBean<RT>((Class)expr.getType(), bindings);
}catch(IllegalAccessException e) {
throw new QueryException(e);
}
}
private CloseableIterator<Object[]> iterateMultiple(QueryMetadata metadata) {
String queryString = buildQueryString(false);
logger.debug("query : {}", queryString);

View File

@ -144,6 +144,17 @@ public abstract class SelectBaseTest extends AbstractBaseTest{
assertNotNull(result[0]);
}
}
@Test
public void RelationalPath_Projection() {
List<Object[]> results = query().from(employee, employee2).where(employee.id.eq(employee2.id)).list(employee, employee2);
assertFalse(results.isEmpty());
for (Object[] row : results) {
Employee e1 = (Employee)row[0];
Employee e2 = (Employee)row[1];
assertEquals(e1.getId(), e2.getId());
}
}
@Test
public void Beans(){