diff --git a/querydsl-jpa/pom.xml b/querydsl-jpa/pom.xml index c8cf557e2..8f3bbccbb 100644 --- a/querydsl-jpa/pom.xml +++ b/querydsl-jpa/pom.xml @@ -126,7 +126,7 @@ com.h2database h2 - 1.2.133 + ${h2.version} test diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java index bf2e78db8..66804ffef 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java +++ b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java @@ -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> 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> 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 rv = new ArrayList(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 iterate(Expression[] args) { return new IteratorAdapter(list(args).iterator()); @@ -176,16 +223,22 @@ public abstract class AbstractJPAQuery> extends JP @SuppressWarnings("unchecked") public List list(Expression[] args) { Query query = createQuery(args); - reset(); - return query.getResultList(); + try { + return (List)getResultList(query); + } finally { + reset(); + } } @Override @SuppressWarnings("unchecked") public List list(Expression expr) { Query query = createQuery(expr); - reset(); - return query.getResultList(); + try { + return (List) getResultList(query); + } finally { + reset(); + } } public SearchResults listResults(Expression expr) { @@ -198,7 +251,7 @@ public abstract class AbstractJPAQuery> extends JP logQuery(queryString); query = createQuery(queryString, modifiers); @SuppressWarnings("unchecked") - List list = query.getResultList(); + List list = (List) getResultList(query); reset(); return new SearchResults(list, modifiers, total); } else { @@ -206,7 +259,7 @@ public abstract class AbstractJPAQuery> 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> 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(); } } diff --git a/querydsl-jpa/src/test/java/com/mysema/query/AbstractJPATest.java b/querydsl-jpa/src/test/java/com/mysema/query/AbstractJPATest.java index ed949f4ef..aae835b8e 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/AbstractJPATest.java +++ b/querydsl-jpa/src/test/java/com/mysema/query/AbstractJPATest.java @@ -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 diff --git a/querydsl-jpa/src/test/java/com/mysema/query/AbstractStandardTest.java b/querydsl-jpa/src/test/java/com/mysema/query/AbstractStandardTest.java index 1ad4a7854..74bf4d83f 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/AbstractStandardTest.java +++ b/querydsl-jpa/src/test/java/com/mysema/query/AbstractStandardTest.java @@ -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()); diff --git a/querydsl-jpa/src/test/java/com/mysema/query/_h2/H2JPAEclipseLinkTest.java b/querydsl-jpa/src/test/java/com/mysema/query/_h2/H2JPAEclipseLinkTest.java index 88b793ba4..9c28bed96 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/_h2/H2JPAEclipseLinkTest.java +++ b/querydsl-jpa/src/test/java/com/mysema/query/_h2/H2JPAEclipseLinkTest.java @@ -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 + } + } diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Employee.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Employee.java index 3cbea27b4..679230ae4 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Employee.java +++ b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Employee.java @@ -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)