| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.openjpa.persistence.query; |
| |
| import java.util.Collection; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import javax.persistence.NoResultException; |
| |
| import org.apache.openjpa.persistence.Extent; |
| import org.apache.openjpa.persistence.OpenJPAEntityManager; |
| import org.apache.openjpa.persistence.OpenJPAQuery; |
| import org.apache.openjpa.persistence.jdbc.FetchMode; |
| import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan; |
| import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1; |
| import org.apache.openjpa.persistence.query.common.apps.RuntimeTest2; |
| import org.apache.openjpa.persistence.query.common.apps.RuntimeTest3; |
| |
| /** |
| * Test that ResultList objects behaver correctly. |
| * |
| * @author Marc Prud'hommeaux |
| */ |
| public class TestQueryResults extends BaseQueryTest { |
| |
| public TestQueryResults(String test) { |
| super(test); |
| } |
| |
| @Override |
| public void setUp() { |
| deleteAll(RuntimeTest1.class); |
| |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| em.persist(new RuntimeTest1("TestQueryResults1", 10)); |
| em.persist(new RuntimeTest1("TestQueryResults3", 10)); |
| em.persist(new RuntimeTest1("TestQueryResults5", 10)); |
| em.persist(new RuntimeTest3("TestQueryResults2", 10)); |
| em.persist(new RuntimeTest3("TestQueryResults4", 10)); |
| em.persist(new RuntimeTest3("TestQueryResults6", 10)); |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testQueryIteratorsReturnFalseForClosedQuery() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery("SELECT o FROM RuntimeTest1 o"); |
| List c = q.getResultList(); |
| Iterator i = c.iterator(); |
| if (!(i.hasNext())) |
| fail("Iterator should have had next()"); |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| |
| if (i.hasNext()) |
| fail("Iterator obtained from Query should return false " |
| + "for hasNext() after Query has been closed"); |
| } |
| |
| public void testQueryIteratorsThrowExceptionForClosedQuery() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery("SELECT o FROM RuntimeTest1 o"); |
| List c = q.getResultList(); |
| Iterator i = c.iterator(); |
| if (!(i.hasNext())) |
| fail("Iterator should have had next()"); |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| |
| try { |
| i.next(); |
| fail("Iterator.next() should have thrown Exception " |
| + "after query.closeAll() was called"); |
| } |
| catch (Exception e) { |
| // |
| } |
| } |
| |
| public void testLazyQueryIteratorsReturnFalseForClosedem() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| String query = "SELECT o FROM RuntimeTest1 o"; |
| OpenJPAQuery q = em.createQuery(query); |
| q.getFetchPlan().setFetchBatchSize(5); |
| List c = q.getResultList(); |
| |
| Iterator i = c.iterator(); |
| if (!(i.hasNext())) |
| fail("Iterator should have had next()"); |
| endTx(em); |
| endEm(em); |
| |
| if (i.hasNext()) |
| fail("Lazy result iterator obtained from Query should return " |
| + "false for hasNext() after em has been closed"); |
| } |
| |
| public void testEagerQueryIteratorsWorkForClosedem() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| String query = "SELECT o FROM RuntimeTest1 o"; |
| OpenJPAQuery q = em.createQuery(query); |
| q.getFetchPlan().setFetchBatchSize(-1); |
| |
| List c = q.getResultList(); |
| |
| Iterator i = c.iterator(); |
| if (!(i.hasNext())) |
| fail("Iterator should have had next()"); |
| endTx(em); |
| endEm(em); |
| |
| if (!i.hasNext()) |
| fail("Eager result iterator obtained from Query should return " |
| + "true for hasNext() after em has been closed"); |
| } |
| |
| public void testQueryResultIsList() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| String query = "SELECT o FROM RuntimeTest1 o"; |
| |
| Collection c = (Collection) em.createQuery(query).getResultList(); |
| if (!(c instanceof List)) |
| fail("Collection (" + c.getClass() + ") should have " |
| + "been a List instance"); |
| |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testQueryResultSizeIsCorrect() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| em.persist(new RuntimeTest2("TestQueryResults1", 10)); |
| endTx(em); |
| endEm(em); |
| |
| em = (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| String query = "SELECT r FROM RuntimeTest2 r WHERE r.stringField = " |
| + "\'TestQueryResults1\'"; |
| List c = em.createQuery(query).getResultList(); |
| |
| assertEquals(1, c.size()); |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testExtentIteratorsReturnFalseForClosedExtent() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| Extent extent = em.createExtent(RuntimeTest1.class, true); |
| |
| Iterator i = extent.iterator(); |
| if (!(i.hasNext())) |
| fail("Iterator should have had next()"); |
| extent.closeAll(); |
| |
| if (i.hasNext()) |
| fail("Iterator obtained from Extent should return false " |
| + "for hasNext() after Extent has been closed"); |
| |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testExtentIteratorsThrowExceptionForClosedExtent() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| Extent extent = em.createExtent(RuntimeTest1.class, true); |
| |
| Iterator i = extent.iterator(); |
| if (!(i.hasNext())) |
| fail("Iterator should have had next()"); |
| extent.closeAll(); |
| |
| try { |
| i.next(); |
| fail("Iterator.next() should have thrown Exception " |
| + "after Extent.closeAll() was called"); |
| } catch (Exception e) { |
| // this is a *good* thing. |
| } |
| |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testExtentIteratorsReturnFalseForClosedem() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| Extent extent = em.createExtent(RuntimeTest1.class, true); |
| Iterator i = extent.iterator(); |
| if (!(i.hasNext())) |
| fail("Iterator should have had next()"); |
| endTx(em); |
| endEm(em); |
| |
| if (i.hasNext()) |
| fail("Iterator obtained from Extent should return false " |
| + "for hasNext() after em has been closed"); |
| } |
| |
| public void testUniqueReturnsSingleResult() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| String query = "SELECT DISTINCT r FROM RuntimeTest1 r WHERE " |
| + "r.stringField = \'TestQueryResults1\'"; |
| Object obj = em.createQuery(query).getSingleResult(); |
| |
| assertTrue(obj instanceof RuntimeTest1); |
| |
| query = "SELECT DISTINCT r FROM RuntimeTest1 r WHERE r.stringField = " |
| + "\'xxxx\'"; |
| OpenJPAQuery q = em.createQuery(query); |
| try { |
| Object l = q.getSingleResult(); |
| fail("Expected NoResultException since there is no RuntimeTest1 " |
| + "instance with stringfield=xxxx"); |
| } catch (NoResultException e) { |
| // good |
| } |
| |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testUniqueThrowsExceptionIfMultipleResults() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| String query = "SELECT DISTINCT r FROM RuntimeTest1 r"; |
| OpenJPAQuery q = em.createQuery(query); |
| |
| try { |
| Object l = q.getSingleResult(); |
| fail("Unique query matched multiple results."); |
| } |
| catch (Exception jue) { |
| } |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testImpossibleRangeReturnsEmptyList() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| String query = "SELECT r FROM RuntimeTest1 r"; |
| OpenJPAQuery q = em.createQuery(query); |
| q.setFirstResult(2); |
| q.setMaxResults(0); |
| |
| List results = q.getResultList(); |
| |
| assertEquals(0, results.size()); |
| assertFalse(results.iterator().hasNext()); |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testImpossibleUniqueRangeReturnsNull() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery("SELECT DISTINCT r FROM RuntimeTest1 r " |
| + "WHERE r.stringField = \'TestQueryResults1\'"); |
| q.setFirstResult(2); |
| q.setMaxResults(0); |
| assertTrue( |
| "resultlist is not null its size is: " + q.getResultList().size(), |
| q.getResultList().isEmpty()); |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testSingleResultUniqueRange() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery("SELECT DISTINCT r FROM RuntimeTest1 r " |
| + "WHERE r.stringField = \'TestQueryResults1\'"); |
| q.setFirstResult(1); |
| q.setMaxResults(1000000); |
| |
| assertTrue("resultlist is not empty", (q.getResultList()).isEmpty()); |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testMultiResultUniqueRange() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery( |
| "SELECT DISTINCT r FROM RuntimeTest1 r ORDER BY r.stringField ASC"); |
| q.setFirstResult(1); |
| q.setMaxResults(2); |
| |
| assertEquals("TestQueryResults2", |
| ((RuntimeTest1) q.getResultList().get(0)).getStringField()); |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| |
| /* This test is being commented because it was supposed to be a converted |
| * test complementing the original JDO test which uses the setUnique() |
| * method available in JDO Query. OpenJPAQuery does not have such a method |
| * and hence this test does not make sense. |
| public void testUniqueThrowsExceptionIfNonUniqueRange() |
| { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery( |
| "SELECT DISTINCT r FROM RuntimeTest1 r ORDER BY r.stringField ASC"); |
| q.setFirstResult(1); |
| q.setMaxResults(3); |
| |
| try |
| { |
| q.getResultList(); |
| fail("Unique allowed non-unique range."); |
| } |
| catch (Exception jue) |
| { |
| } |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| */ |
| public void testFullRange() { |
| try { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery( |
| "SELECT r FROM RuntimeTest1 ORDER BY r.stringField ASC"); |
| q.setSubclasses(false); |
| q.setFirstResult(0); |
| Long l = Long.MAX_VALUE; |
| q.setMaxResults(l.intValue()); |
| |
| List res = (List) q.getResultList(); |
| assertEquals(3, res.size()); |
| for (int i = 0; i < res.size(); i++) |
| assertEquals("TestQueryResults" + (i * 2 + 1), |
| ((RuntimeTest1) res.get(i)).getStringField()); |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| catch (Exception uoe) { |
| //FIXME:AFAM -- Figure out JPA Equivalence of createExtent(class, |
| //false) ie how to restrict the query result to the base entity and |
| //not the subclasses |
| } |
| } |
| |
| public void testFullRangeSubs() { |
| try { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery( |
| "SELECT r FROM RuntimeTest1 ORDER BY r.stringField ASC"); |
| q.setFirstResult(0); |
| Long l = Long.MAX_VALUE; |
| q.setMaxResults(l.intValue()); |
| |
| List res = (List) q.getResultList(); |
| assertEquals(6, res.size()); |
| for (int i = 0; i < res.size(); i++) |
| assertEquals("TestQueryResults" + (i + 1), |
| ((RuntimeTest1) res.get(i)).getStringField()); |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| catch (Exception uoe) { |
| } |
| } |
| |
| public void testBeginRange() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery( |
| "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC"); |
| q.setSubclasses(false); |
| for (int i = 0; i < 4; i++) { |
| q.setFirstResult(i); |
| q.setMaxResults(100000); |
| |
| List res = (List) q.getResultList(); |
| assertEquals("they are not equal", 3 - i, res.size()); |
| int idx = 0; |
| |
| // try both random acess and iteration |
| for (int j = 0; j < res.size(); j++) |
| assertEquals("TestQueryResults" + (j * 2 + 1 + i * 2), |
| (((RuntimeTest1) res.get(j)).getStringField())); |
| for (Iterator itr = res.iterator(); itr.hasNext(); idx++) |
| assertEquals("TestQueryResults" + (idx * 2 + 1 + i * 2), |
| ((RuntimeTest1) itr.next()).getStringField()); |
| } |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testBeginRangeSubs() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery( |
| "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC"); |
| |
| for (int i = 0; i < 7; i++) { |
| q.setFirstResult(i); |
| Long l = Long.MAX_VALUE; |
| q.setMaxResults(100000); |
| |
| List res = (List) q.getResultList(); |
| assertEquals(6 - i, res.size()); |
| int idx = 0; |
| |
| // try both random acess and iteration |
| for (int j = 0; j < res.size(); j++) |
| assertEquals("TestQueryResults" + (j + 1 + i), |
| ((RuntimeTest1) res.get(j)).getStringField()); |
| for (Iterator itr = res.iterator(); itr.hasNext(); idx++) |
| assertEquals("TestQueryResults" + (idx + 1 + i), |
| ((RuntimeTest1) itr.next()).getStringField()); |
| } |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testEndRange() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery( |
| "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC"); |
| q.setSubclasses(false); |
| |
| for (int i = 0; i < 4; i++) { |
| q.setFirstResult(0); |
| q.setMaxResults(i); |
| |
| List res = (List) q.getResultList(); |
| assertEquals(i, res.size()); |
| int idx = 0; |
| |
| // try both random acess and iteration |
| for (int j = 0; j < res.size(); j++) |
| assertEquals("TestQueryResults" + (j * 2 + 1), |
| ((RuntimeTest1) res.get(j)).getStringField()); |
| for (Iterator itr = res.iterator(); itr.hasNext(); idx++) |
| assertEquals("TestQueryResults" + (idx * 2 + 1), |
| ((RuntimeTest1) itr.next()).getStringField()); |
| } |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testEndRangeSubs() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery( |
| "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC"); |
| |
| for (int i = 0; i < 7; i++) { |
| q.setFirstResult(0); |
| q.setMaxResults(i); |
| List res = (List) q.getResultList(); |
| assertEquals(i, res.size()); |
| int idx = 0; |
| |
| // try both random acess and iteration |
| for (int j = 0; j < res.size(); j++) |
| assertEquals("TestQueryResults" + (j + 1), |
| ((RuntimeTest1) res.get(j)).getStringField()); |
| for (Iterator itr = res.iterator(); itr.hasNext(); idx++) |
| assertEquals("TestQueryResults" + (idx + 1), |
| ((RuntimeTest1) itr.next()).getStringField()); |
| } |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testMidRange() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery( |
| "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC"); |
| q.setSubclasses(false); |
| |
| q.setFirstResult(1); |
| q.setMaxResults(3); |
| List res = (List) q.getResultList(); |
| assertEquals(2, res.size()); |
| for (int i = 0; i < res.size(); i++) |
| assertEquals("TestQueryResults" + (i * 2 + 1 + 2), |
| ((RuntimeTest1) res.get(i)).getStringField()); |
| int idx = 0; |
| for (Iterator itr = res.iterator(); itr.hasNext(); idx++) |
| assertEquals("TestQueryResults" + (idx * 2 + 1 + 2), |
| ((RuntimeTest1) itr.next()).getStringField()); |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testMidRangeSubs() { |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery( |
| "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC"); |
| q.setFirstResult(1); |
| q.setMaxResults(3); |
| |
| List res = (List) q.getResultList(); |
| assertEquals(3, res.size()); |
| for (int i = 0; i < res.size(); i++) |
| assertEquals("TestQueryResults" + (i + 1 + 1), |
| ((RuntimeTest1) res.get(i)).getStringField()); |
| int idx = 0; |
| for (Iterator itr = res.iterator(); itr.hasNext(); idx++) |
| assertEquals("TestQueryResults" + (idx + 1 + 1), |
| ((RuntimeTest1) itr.next()).getStringField()); |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| |
| public void testPessimisticOrderedRange() { |
| // test to make sure whatever machinations we do to get a range doesn't |
| // interfere with FOR UPDATE |
| OpenJPAEntityManager em = |
| (OpenJPAEntityManager) currentEntityManager(); |
| startTx(em); |
| |
| OpenJPAQuery q = em.createQuery( |
| "SELECT r FROM RuntimeTest1 r ORDER BY r.stringField ASC"); |
| q.setSubclasses(false); |
| q.setFirstResult(0); |
| q.setMaxResults(2); |
| |
| ((JDBCFetchPlan) q.getFetchPlan()).setEagerFetchMode(FetchMode.NONE); |
| |
| List res = (List) q.getResultList(); |
| assertEquals(2, res.size()); |
| assertEquals("TestQueryResults1", |
| ((RuntimeTest1) res.get(0)).getStringField()); |
| assertEquals("TestQueryResults3", |
| ((RuntimeTest1) res.get(1)).getStringField()); |
| q.closeAll(); |
| endTx(em); |
| endEm(em); |
| } |
| } |
| |