added result transformation support for non-Hibernate JPA providers

This commit is contained in:
Timo Westkämper 2011-07-05 14:03:11 +00:00
parent e741a8b308
commit 9ee7551686
6 changed files with 143 additions and 27 deletions

View File

@ -126,7 +126,7 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.2.133</version>
<version>${h2.version}</version>
<scope>test</scope>
</dependency>

View File

@ -6,6 +6,7 @@
package com.mysema.query.jpa.impl;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -52,6 +53,8 @@ public abstract class AbstractJPAQuery<Q extends AbstractJPAQuery<Q>> extends JP
private Class<?> hibernateQueryClass;
private boolean factoryExpressionUsed = false;
public AbstractJPAQuery(EntityManager em) {
this(new DefaultSessionHolder(em), HQLTemplates.DEFAULT, new DefaultQueryMetadata());
}
@ -156,13 +159,57 @@ public abstract class AbstractJPAQuery<Q extends AbstractJPAQuery<Q>> extends JP
} catch (NoSuchMethodException e) {
throw new QueryException(e.getMessage(), e);
}
} else {
factoryExpressionUsed = true;
}
}
}
return query;
}
/**
* Transforms results using FactoryExpression if ResultTransformer can't be used
*
* @param query
* @return
*/
private List<?> getResultList(Query query) {
// TODO : use lazy list here?
if (factoryExpressionUsed) {
List<?> results = query.getResultList();
List<Object> rv = new ArrayList<Object>(results.size());
FactoryExpression<?> expr = (FactoryExpression<?>)getMetadata().getProjection().get(0);
for (Object o : results) {
if (o != null && !o.getClass().isArray()){
o = new Object[]{o};
}
rv.add(expr.newInstance((Object[])o));
}
return rv;
} else {
return query.getResultList();
}
}
/**
* Transforms results using FactoryExpression if ResultTransformer can't be used
*
* @param query
* @return
*/
private Object getSingleResult(Query query) {
if (factoryExpressionUsed) {
Object result = query.getSingleResult();
FactoryExpression<?> expr = (FactoryExpression<?>)getMetadata().getProjection().get(0);
if (result != null && !result.getClass().isArray()) {
result = new Object[]{result};
}
return expr.newInstance((Object[])result);
} else {
return query.getSingleResult();
}
}
public CloseableIterator<Object[]> iterate(Expression<?>[] args) {
return new IteratorAdapter<Object[]>(list(args).iterator());
@ -176,16 +223,22 @@ public abstract class AbstractJPAQuery<Q extends AbstractJPAQuery<Q>> extends JP
@SuppressWarnings("unchecked")
public List<Object[]> list(Expression<?>[] args) {
Query query = createQuery(args);
reset();
return query.getResultList();
try {
return (List<Object[]>)getResultList(query);
} finally {
reset();
}
}
@Override
@SuppressWarnings("unchecked")
public <RT> List<RT> list(Expression<RT> expr) {
Query query = createQuery(expr);
reset();
return query.getResultList();
try {
return (List<RT>) getResultList(query);
} finally {
reset();
}
}
public <RT> SearchResults<RT> listResults(Expression<RT> expr) {
@ -198,7 +251,7 @@ public abstract class AbstractJPAQuery<Q extends AbstractJPAQuery<Q>> extends JP
logQuery(queryString);
query = createQuery(queryString, modifiers);
@SuppressWarnings("unchecked")
List<RT> list = query.getResultList();
List<RT> list = (List<RT>) getResultList(query);
reset();
return new SearchResults<RT>(list, modifiers, total);
} else {
@ -206,7 +259,7 @@ public abstract class AbstractJPAQuery<Q extends AbstractJPAQuery<Q>> extends JP
return SearchResults.emptyResults();
}
}
protected void logQuery(String queryString){
if (logger.isDebugEnabled()){
logger.debug(queryString.replace('\n', ' '));
@ -230,15 +283,16 @@ public abstract class AbstractJPAQuery<Q extends AbstractJPAQuery<Q>> extends JP
private Object uniqueResult() {
String queryString = toQueryString();
logQuery(queryString);
Query query = createQuery(queryString, getMetadata().getModifiers());
reset();
Query query = createQuery(queryString, getMetadata().getModifiers());
try{
return query.getSingleResult();
}catch(javax.persistence.NoResultException e){
return getSingleResult(query);
} catch(javax.persistence.NoResultException e){
logger.debug(e.getMessage(),e);
return null;
}catch(javax.persistence.NonUniqueResultException e){
} catch(javax.persistence.NonUniqueResultException e){
throw new NonUniqueResultException();
} finally {
reset();
}
}

View File

@ -73,14 +73,14 @@ public abstract class AbstractJPATest extends AbstractStandardTest{
@Test
public void LockMode(){
javax.persistence.Query query = query().from(QCat.cat).setLockMode(LockModeType.READ).createQuery(QCat.cat);
assertTrue(query.getLockMode().equals(LockModeType.READ));
javax.persistence.Query query = query().from(QCat.cat).setLockMode(LockModeType.PESSIMISTIC_READ).createQuery(QCat.cat);
assertTrue(query.getLockMode().equals(LockModeType.PESSIMISTIC_READ));
assertFalse(query.getResultList().isEmpty());
}
@Test
public void LockMode2(){
assertFalse(query().from(QCat.cat).setLockMode(LockModeType.READ).list(QCat.cat).isEmpty());
assertFalse(query().from(QCat.cat).setLockMode(LockModeType.PESSIMISTIC_READ).list(QCat.cat).isEmpty());
}
@Test

View File

@ -215,6 +215,11 @@ public abstract class AbstractStandardTest {
assertTrue(catQuery().where(cat.kittens.any().name.eq("XXX")).notExists());
}
@Test
public void Any_Usage(){
assertEquals(1, catQuery().where(cat.kittens.any().name.eq("Ruth123")).count());
}
@Test
public void Any_And_Lt(){
assertEquals(1, catQuery().where(cat.kittens.any().name.eq("Ruth123"), cat.kittens.any().bodyWeight.lt(10.0)).count());

View File

@ -5,13 +5,19 @@
*/
package com.mysema.query._h2;
import org.junit.Ignore;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.eclipse.persistence.config.HintValues;
import org.eclipse.persistence.config.QueryHints;
import org.junit.runner.RunWith;
import com.mysema.query.AbstractJPATest;
import com.mysema.query.Target;
import com.mysema.query.jpa.EclipseLinkTemplates;
import com.mysema.query.jpa.JPQLTemplates;
import com.mysema.query.jpa.domain.QCat;
import com.mysema.testutil.JPAConfig;
import com.mysema.testutil.JPATestRunner;
@ -19,7 +25,7 @@ import com.mysema.testutil.JPATestRunner;
* @author tiwe
*
*/
@Ignore
//@Ignore
@RunWith(JPATestRunner.class)
@JPAConfig("h2-eclipselink")
public class H2JPAEclipseLinkTest extends AbstractJPATest{
@ -33,5 +39,63 @@ public class H2JPAEclipseLinkTest extends AbstractJPATest{
protected Target getTarget() {
return Target.H2;
}
@Override
public void Hint(){
javax.persistence.Query query = query().from(QCat.cat).setHint(QueryHints.BIND_PARAMETERS, HintValues.PERSISTENCE_UNIT_DEFAULT).createQuery(QCat.cat);
assertNotNull(query);
assertTrue(query.getHints().containsKey(QueryHints.BIND_PARAMETERS));
assertFalse(query.getResultList().isEmpty());
}
@Override
public void Connection_Access(){
// cannot unwrap to Connection instance
}
@Override
public void Map_ContainsKey(){
// not supported
}
@Override
public void Map_ContainsKey2(){
// not supported
}
@Override
public void Map_ContainsKey3(){
// not supported
}
@Override
public void Map_ContainsValue(){
// not supported
}
@Override
public void Map_ContainsValue2(){
// not supported
}
@Override
public void Map_ContainsValue3(){
// not supported
}
@Override
public void test(){
// FIXME
}
@Override
public void Any_And_Lt(){
// FIXME
}
@Override
public void Any_And_Gt(){
// FIXME
}
}

View File

@ -8,15 +8,7 @@ package com.mysema.query.jpa.domain;
import java.util.Collection;
import java.util.HashSet;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.*;
/**
* The Class Employee.
@ -32,6 +24,7 @@ public class Employee {
public String firstName, lastName;
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)
public int id;
@Enumerated(EnumType.STRING)