Author: jrbauer Date: Mon Mar 30 17:21:57 2009 New Revision: 760056 URL: http://svn.apache.org/viewvc?rev=760056&view=rev Log: OPENJPA-990 Committing code and test updates contributed by Donald Woods
Modified: openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/util/localizer.properties openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestQueryHints.java openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryTimeout.java Modified: openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties?rev=760056&r1=760055&r2=760056&view=diff ============================================================================== --- openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties (original) +++ openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties Mon Mar 30 17:21:57 2009 @@ -186,4 +186,6 @@ long-seq-name: Sequence name "{0}" is {1}-character long. The database allows \ maximum {2}-character for a sequence name. null-blob-in-not-nullable: Can not set null value on column "{0}" \ - because the corresponding field is set to be non-nullable. \ No newline at end of file + because the corresponding field is set to be non-nullable. +invalid-timeout: An invalid timeout of {0} milliseconds was ignored. \ + Expected a value that is greater than or equal to zero. Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java?rev=760056&r1=760055&r2=760056&view=diff ============================================================================== --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java (original) +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java Mon Mar 30 17:21:57 2009 @@ -423,8 +423,14 @@ public FetchConfiguration setLockTimeout(int timeout) { if (timeout == DEFAULT && _state.ctx != null) _state.lockTimeout = _state.ctx.getConfiguration().getLockTimeout(); - else if (timeout != DEFAULT) - _state.lockTimeout = timeout; + else if (timeout != DEFAULT) { + if (timeout < -1) { + throw new IllegalArgumentException(_loc.get("invalid-timeout", + timeout).getMessage()); + } else { + _state.lockTimeout = timeout; + } + } return this; } @@ -434,9 +440,16 @@ public FetchConfiguration setQueryTimeout(int timeout) { if (timeout == DEFAULT && _state.ctx != null) - _state.queryTimeout = _state.ctx.getConfiguration().getQueryTimeout(); - else if (timeout != DEFAULT) - _state.queryTimeout = timeout; + _state.queryTimeout = _state.ctx.getConfiguration(). + getQueryTimeout(); + else if (timeout != DEFAULT) { + if (timeout < -1) { + throw new IllegalArgumentException(_loc.get("invalid-timeout", + timeout).getMessage()); + } else { + _state.queryTimeout = timeout; + } + } return this; } Modified: openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties?rev=760056&r1=760055&r2=760056&view=diff ============================================================================== --- openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties (original) +++ openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties Mon Mar 30 17:21:57 2009 @@ -406,4 +406,6 @@ bound parameters with following values "{3}". This can happen if you have \ declared but missed to bind values for one or more parameters. query-execution-error: Failed to execute query "{0}". Check the query syntax \ - for correctness. See nested exception for details. \ No newline at end of file + for correctness. See nested exception for details. +invalid-timeout: An invalid timeout of {0} milliseconds was ignored. \ + Expected a value that is greater than or equal to -1. Modified: openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/util/localizer.properties URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/util/localizer.properties?rev=760056&r1=760055&r2=760056&view=diff ============================================================================== --- openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/util/localizer.properties (original) +++ openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/util/localizer.properties Mon Mar 30 17:21:57 2009 @@ -75,5 +75,3 @@ abstract class "{0}". query-failed: A query statement timeout has occurred. query-timeout: A query statement timeout (set to {0} milliseconds) has occurred. -invalid-timeout: An invalid timeout of {0} milliseconds was ignored. \ - Expected a value that is greater than or equal to zero. Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestQueryHints.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestQueryHints.java?rev=760056&r1=760055&r2=760056&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestQueryHints.java (original) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/conf/TestQueryHints.java Mon Mar 30 17:21:57 2009 @@ -142,6 +142,24 @@ assertEquals(5671, query.getFetchPlan().getLockTimeout()); assertEquals(7500, query.getFetchPlan().getQueryTimeout()); } + + public void testInvalidLockTimeoutHint() { + try { + query.setHint("javax.persistence.lock.timeout", -5671); + fail("Expected setHint to fail with an IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // expected + } + } + + public void testInvalidQueryTimeoutHint() { + try { + query.setHint("javax.persistence.query.timeout", -7500); + fail("Expected setHint to fail with an IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // expected + } + } public void testParts() { HintHandler.HintKeyComparator test = new HintHandler.HintKeyComparator(); Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryTimeout.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryTimeout.java?rev=760056&r1=760055&r2=760056&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryTimeout.java (original) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestQueryTimeout.java Mon Mar 30 17:21:57 2009 @@ -59,8 +59,9 @@ * b) getSingleResult() * c) executeUpdate() * Other behaviors to test for: - * 4) Setting timeout to < 0 should be treated as no timeout supplied - * 5) Updates after EM.find()/findAll() are not affected by query timeout + * 4) Setting timeout to -1 should be treated as no timeout supplied + * 5) Setting timeout to < -1 should throw an IllegalArgumentExpection + * 6) Updates after EM.find()/findAll() are not affected by query timeout * Exception generation to test for: * If the DB query timeout does not cause a transaction rollback, then a * QueryTimeoutException should be thrown. @@ -222,7 +223,8 @@ try { em = emf.createEntityManager(); assertNotNull(em); - Query q = em.createQuery("UPDATE QTimeout q SET q.stringField = :strVal WHERE q.id = 1"); + Query q = em.createQuery("UPDATE QTimeout q SET q.stringField = " + + ":strVal WHERE q.id = 1"); q.setParameter("strVal", new String("updated")); // verify no default javax.persistence.query.timeout is supplied Map<String, Object> hints = q.getHints(); @@ -341,8 +343,8 @@ List results = q.getResultList(); long endTime = System.currentTimeMillis(); long runTime = endTime - startTime; - getLog().trace("testQueryTimeout22a() - Hint0msec runTime msecs=" - + runTime); + getLog().trace("testQueryTimeout22a() - Hint0msec runTime " + + "msecs=" + runTime); // Hack - Windows sometimes returns 5999 instead of 6000+ assertTrue("Should have taken 6+ secs, but was msecs=" + runTime, runTime > 5900); @@ -422,7 +424,8 @@ if (skipTests) { return; } - getLog().trace("testQueryTimeout31c() - PU(timeout=1000), executeUpdate timeout"); + getLog().trace("testQueryTimeout31c() - PU(timeout=1000), " + + "executeUpdate timeout"); OpenJPAEntityManagerFactory emf = null; OpenJPAEntityManager em = null; Integer setTime = new Integer(1000); @@ -440,7 +443,8 @@ // create EM and Query em = emf.createEntityManager(); assertNotNull(em); - OpenJPAQuery q = em.createNativeQuery("UPDATE QTimeout SET stringField = ? WHERE mod(DELAY(2,id),2)=0"); + OpenJPAQuery q = em.createNativeQuery("UPDATE QTimeout SET " + + "stringField = ? WHERE mod(DELAY(2,id),2)=0"); q.setParameter(1, new String("updated")); // verify no default javax.persistence.query.timeout is supplied Map<String, Object> hints = q.getHints(); @@ -457,8 +461,8 @@ em.getTransaction().commit(); long endTime = System.currentTimeMillis(); long runTime = endTime - startTime; - getLog().trace("testQueryTimeout31c() - executeUpdate runTime " + - "msecs=" + runTime); + getLog().trace("testQueryTimeout31c() - executeUpdate " + + "runTime msecs=" + runTime); fail("QueryTimeout for executeUpdate failed to cause an " + "Exception in testQueryTimeout31c(" + setTime + " mscs), runTime msecs=" + runTime); @@ -485,7 +489,8 @@ if (skipTests) { return; } - getLog().trace("testQueryTimeout32a() - PU(1000), Map(0), QueryHint(1000)"); + getLog().trace("testQueryTimeout32a() - PU(1000), Map(0), " + + "QueryHint(1000)"); OpenJPAEntityManagerFactory emf = null; OpenJPAEntityManager em = null; Integer setTime = new Integer(0); @@ -587,7 +592,8 @@ getLog().trace( "testQueryTimeout33b() - NoHintSingle runTime msecs=" + runTime); - //assertNull("Should never get valid result due to the timeout.", result); + //assertNull("Should never get valid result due to the timeout." + // , result); fail("QueryTimeout annotation failed to cause an Exception " + "in testQueryTimeout33b(" + setTime + " mscs), runTime msecs=" + runTime); @@ -612,7 +618,8 @@ if (skipTests) { return; } - getLog().trace("testQueryTimeout33c() - PU(timeout=0), setHint(1000), executeUpdate timeout"); + getLog().trace("testQueryTimeout33c() - PU(timeout=0), setHint(1000)," + + " executeUpdate timeout"); OpenJPAEntityManagerFactory emf = null; OpenJPAEntityManager em = null; Integer setTime = new Integer(0); @@ -631,13 +638,16 @@ em = emf.createEntityManager(); assertNotNull(em); // Following fails to cause a SQLException, but takes 2+ secs - // Query q = em.createQuery("UPDATE QTimeout q SET q.stringField = :strVal WHERE q.id > 0"); + // Query q = em.createQuery("UPDATE QTimeout q SET q.stringField = + // + ":strVal WHERE q.id > 0"); // q.setParameter("strVal", new String("updated")); // Following fails to cause a SQLException, but takes 2+ secs - // Query q = em.createNativeQuery("INSERT INTO QTimeout (id, stringField) VALUES (?,?)"); + // Query q = em.createNativeQuery("INSERT INTO QTimeout (id, " + + // "stringField) VALUES (?,?)"); // q.setParameter(1, 99); // q.setParameter(2, new String("inserted")); - OpenJPAQuery q = em.createNativeQuery("UPDATE QTimeout SET stringField = ? WHERE mod(DELAY(2,id),2)=0"); + OpenJPAQuery q = em.createNativeQuery("UPDATE QTimeout SET " + + "stringField = ? WHERE mod(DELAY(2,id),2)=0"); q.setParameter(1, new String("updated")); // verify no default javax.persistence.query.timeout is supplied Map<String, Object> hints = q.getHints(); @@ -663,8 +673,8 @@ em.getTransaction().commit(); long endTime = System.currentTimeMillis(); long runTime = endTime - startTime; - getLog().trace("testQueryTimeout33c() - executeUpdate runTime " + - "msecs=" + runTime); + getLog().trace("testQueryTimeout33c() - executeUpdate " + + "runTime msecs=" + runTime); fail("QueryTimeout for executeUpdate failed to cause an " + "Exception in testQueryTimeout33c(" + setTime + " mscs), runTime msecs=" + runTime); @@ -682,8 +692,8 @@ } /** - * Scenario being tested: 4) Timeouts < 0 are ignored and treated as the - * default no timeout scenario. + * Scenario being tested: 4) Timeout of -1 should be treated the same + * as the default no timeout scenario. * Expected Results: The DELAY function is being called and the query * takes 2000+ msecs to complete. */ @@ -691,7 +701,7 @@ if (skipTests) { return; } - Integer setTime = new Integer(-2000); + Integer setTime = new Integer(-1); getLog().trace("testQueryTimeout4() - setHint(" + setTime + ")"); EntityManager em = null; try { @@ -703,7 +713,7 @@ Map<String, Object> hints = q.getHints(); assertFalse(hints.containsKey("javax.persistence.query.timeout")); - // update the timeout value to -2000 and verify it was set + // update the timeout value to -1 and verify it was set getLog().trace("testQueryTimeout4() - Setting hint " + "javax.persistence.query.timeout=" + setTime); @@ -740,16 +750,55 @@ } /** - * Scenario being tested: 5) PU Query timeout hints do not affect EM + * Scenario being tested: 5) Setting timeout to < -1 should throw an + * IllegalArgumentExpection + * Expected Results: IllegalArgumentException + */ + public void testQueryTimeout5() { + if (skipTests) { + return; + } + Integer setTime = new Integer(-2000); + getLog().trace("testQueryTimeout5() - setHint(" + setTime + ")"); + EntityManager em = null; + try { + em = emf.createEntityManager(); + assertNotNull(em); + Query q = em.createNamedQuery("NoHintSingle"); + + // verify no default javax.persistence.query.timeout is supplied + Map<String, Object> hints = q.getHints(); + assertFalse(hints.containsKey("javax.persistence.query.timeout")); + + // update the timeout value to -2000 and verify it was set + getLog().trace("testQueryTimeout5() - Setting hint " + + "javax.persistence.query.timeout=" + + setTime); + q.setHint("javax.persistence.query.timeout", setTime); + fail("Expected testQueryTimeout5() to throw a " + + "IllegalArgumentException"); + } catch (Exception e) { + // expected - setHint(-2000) should cause an IllegalArgumentException + checkException("testQueryTimeout5()", e, + IllegalArgumentException.class, "Invalid value" ); + } finally { + if ((em != null) && em.isOpen()) { + em.close(); + } + } + } + + /** + * Scenario being tested: 6) PU Query timeout hints do not affect EM * operations like updating Entities returned by EM.find()/findAll() * Expected Results: The DELAY function is being called and the update * takes 2000+ msecs to complete. */ - public void testQueryTimeout5() { + public void testQueryTimeout6() { if (skipTests) { return; } - getLog().trace("testQueryTimeout5() - No EM.find() update timeout"); + getLog().trace("testQueryTimeout6() - No EM.find() update timeout"); OpenJPAEntityManagerFactory emf = null; OpenJPAEntityManager em = null; Integer setTime = new Integer(1000); @@ -777,7 +826,7 @@ em.getTransaction().commit(); long endTime = System.currentTimeMillis(); long runTime = endTime - startTime; - getLog().trace("testQueryTimeout1d() - EM find/update runTime" + + getLog().trace("testQueryTimeout6() - EM find/update runTime" + " msecs=" + runTime); // Hack - Windows sometimes returns 1999 instead of 2000+ assertTrue("Should have taken 2+ secs, but was msecs=" + @@ -789,7 +838,7 @@ } catch (Exception e) { // setting a timeout property via PU or Map shouldn't cause a // timeout exception - fail("Unexpected testQueryTimeout5() exception = " + e); + fail("Unexpected testQueryTimeout6() exception = " + e); } } finally { if ((em != null) && em.isOpen()) { @@ -857,10 +906,11 @@ * @param e */ private void checkException(String test, Exception e) { + String eStr = new String("query statement timeout"); // no easy way to determine exact Exception type for all DBs assertTrue(test + " - UNEXPECTED Exception = " + e, - matchesExpectedException(QueryTimeoutException.class, e) || - matchesExpectedException(PersistenceException.class, e)); + matchesExpectedException(QueryTimeoutException.class, e, eStr) || + matchesExpectedException(PersistenceException.class, e, eStr)); getLog().trace(test + " - Caught expected Exception = " + e); } @@ -868,21 +918,38 @@ * Internal convenience method for checking that the given Exception matches * the expected type. * + * @param test case name + * @param tested exception type + * @param expected exception type + * @param eStr an optional substring to match in the exception text + */ + private void checkException(String test, Exception tested, Class expected, + String eStr) { + assertTrue(test + " - UNEXPECTED Exception = " + tested, + matchesExpectedException(expected, tested, eStr)); + getLog().trace(test + " - Caught expected Exception = " + tested); + } + + /** + * Internal convenience method for checking that the given Exception matches + * the expected type. + * * @param expected * @param tested - * @return + * @param eStr an optional substring to match in the exception text + * @return true if the exception matched, false otherwise */ private boolean matchesExpectedException(Class<?> expected, - Exception tested) { + Exception tested, String eStr) { assertNotNull(expected); boolean exMatched = false; if (tested != null) { Class<?> testExClass = tested.getClass(); exMatched = expected.isAssignableFrom(testExClass); - if (exMatched) { + if (exMatched && eStr != null) { // make sure it is our expected exception text from // localizer.properties - exMatched = (tested.getMessage().indexOf("query statement timeout") != -1); + exMatched = (tested.getMessage().indexOf(eStr) != -1); } } return exMatched;