| /* |
| * 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.conf; |
| |
| import javax.persistence.EntityManager; |
| import javax.persistence.Query; |
| |
| import org.apache.openjpa.jdbc.sql.MariaDBDictionary; |
| import org.apache.openjpa.jdbc.sql.MySQLDictionary; |
| import org.apache.openjpa.jdbc.sql.OracleDictionary; |
| import org.apache.openjpa.kernel.QueryHints; |
| import org.apache.openjpa.persistence.OpenJPAPersistence; |
| import org.apache.openjpa.persistence.OpenJPAQuery; |
| import org.apache.openjpa.persistence.jdbc.IsolationLevel; |
| import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan; |
| import org.apache.openjpa.persistence.test.SingleEMFTestCase; |
| |
| /** |
| * Tests JPA 2.0 API methods {@link Query#getSupportedHints()} and |
| * {@link Query#getHints()}. |
| * |
| * @author Pinaki Poddar |
| * |
| */ |
| public class TestQueryHints extends SingleEMFTestCase { |
| EntityManager em; |
| OpenJPAQuery<?> query; |
| |
| @Override |
| public void setUp() { |
| super.setUp((Object[])null); |
| em = emf.createEntityManager(); |
| String sql = "select * from Person"; |
| query = OpenJPAPersistence.cast(em.createNativeQuery(sql)); |
| } |
| |
| public void testSupportedHintsContainProductDerivationHints() { |
| assertSupportedHint(OracleDictionary.SELECT_HINT, true); |
| assertSupportedHint(MySQLDictionary.SELECT_HINT, true); |
| assertSupportedHint(MariaDBDictionary.SELECT_HINT, true); |
| } |
| |
| public void testSupportedHintsContainFetchPlanHints() { |
| assertSupportedHint("openjpa.FetchPlan.LockTimeout", true); |
| } |
| |
| public void testSupportedHintsIgnoresSomeFetchPlanBeanStyleProperty() { |
| assertSupportedHint("openjpa.FetchPlan.QueryResultCache", false); |
| } |
| |
| public void testSupportedHintsContainQueryProperty() { |
| assertSupportedHint("openjpa.Subclasses", true); |
| } |
| |
| public void testSupportedHintsContainKernelQueryHints() { |
| assertSupportedHint(QueryHints.HINT_IGNORE_PREPARED_QUERY, true); |
| } |
| |
| public void testSupportedHintsContainJPAQueryHints() { |
| assertSupportedHint("javax.persistence.query.timeout", true); |
| } |
| |
| public void testUnrecognizedKeyIsIgnored() { |
| String unrecognizedKey = "acme.org.hint.SomeThingUnknown"; |
| query.setHint(unrecognizedKey, "xyz"); |
| assertFalse(query.getHints().containsKey(unrecognizedKey)); |
| assertNull(query.getFetchPlan().getDelegate().getHint(unrecognizedKey)); |
| } |
| |
| public void testRecognizedKeyIsNotRecordedButAvailable() { |
| String recognizedKey = "openjpa.some.derivation.hint"; |
| query.setHint(recognizedKey, "abc"); |
| assertFalse(query.getHints().containsKey(recognizedKey)); |
| assertEquals("abc", query.getFetchPlan().getDelegate().getHint( |
| recognizedKey)); |
| } |
| |
| public void testSupportedKeyIsRecordedAndAvailable() { |
| String supportedKey = "openjpa.FetchPlan.FetchBatchSize"; |
| query.setHint(supportedKey, 42); |
| assertTrue(query.getHints().containsKey(supportedKey)); |
| assertEquals(42, query.getFetchPlan().getFetchBatchSize()); |
| } |
| |
| public void testSupportedKeyWrongValue() { |
| String supportedKey = "openjpa.FetchPlan.FetchBatchSize"; |
| short goodValue = (short)42; |
| float badValue = 57.9f; |
| query.setHint(supportedKey, goodValue); |
| assertTrue(query.getHints().containsKey(supportedKey)); |
| assertEquals(goodValue, query.getFetchPlan().getFetchBatchSize()); |
| |
| try { |
| query.setHint(supportedKey, badValue); |
| fail("Expected to fail to set " + supportedKey + " hint to " |
| + badValue); |
| } catch (IllegalArgumentException e) { |
| // good |
| } |
| } |
| |
| public void testSupportedKeyIntegerValueConversion() { |
| String supportedKey = "openjpa.hint.OptimizeResultCount"; |
| String goodValue = "57"; |
| int badValue = -3; |
| query.setHint(supportedKey, goodValue); |
| assertTrue(query.getHints().containsKey(supportedKey)); |
| assertEquals(57, query.getFetchPlan().getDelegate().getHint( |
| supportedKey)); |
| |
| try { |
| query.setHint(supportedKey, badValue); |
| fail("Expected to fail to set " + supportedKey + " hint to " |
| + badValue); |
| } catch (IllegalArgumentException e) { |
| // good |
| } |
| } |
| |
| public void testSupportedKeyBooleanValueConversion() { |
| String supportedKey = QueryHints.HINT_IGNORE_PREPARED_QUERY; |
| String goodValue = "true"; |
| query.setHint(supportedKey, goodValue); |
| assertTrue(query.getHints().containsKey(supportedKey)); |
| assertEquals(true, query.getFetchPlan().getDelegate().getHint( |
| supportedKey)); |
| |
| goodValue = "false"; |
| query.setHint(supportedKey, goodValue); |
| assertTrue(query.getHints().containsKey(supportedKey)); |
| assertEquals(false, query.getFetchPlan().getDelegate().getHint( |
| supportedKey)); |
| } |
| |
| public void testJPAHintSetsFetchPlan() { |
| query.setHint("javax.persistence.lock.timeout", 5671); |
| query.setHint("javax.persistence.query.timeout", 7500); |
| 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 |
| } |
| } |
| |
| /** |
| * Verifies a valid fetchplan isolation level hint can be set and retrieved. |
| */ |
| public void testFetchPlanIsolation() { |
| query.setHint("openjpa.FetchPlan.Isolation", "SERIALIZABLE"); |
| assertTrue(query.getHints().containsKey("openjpa.FetchPlan.Isolation")); |
| assertEquals(IsolationLevel.SERIALIZABLE, ((JDBCFetchPlan)query.getFetchPlan()).getIsolation()); |
| } |
| |
| /** |
| * Verifies an invalid fetchplan isolation level hint is ignored. |
| */ |
| public void testInvalidFetchPlanIsolation() { |
| query.setHint("openjpa.FetchPlan.TransactionIsolation", "SERIALIZABLE"); |
| assertFalse(query.getHints().containsKey("openjpa.FetchPlan.TransactionIsolation")); |
| assertNotEquals(IsolationLevel.SERIALIZABLE, ((JDBCFetchPlan)query.getFetchPlan()).getIsolation()); |
| } |
| |
| void assertSupportedHint(String hint, boolean contains) { |
| if (contains) |
| assertTrue("Expected supported hint [" + hint + "]", |
| query.getSupportedHints().contains(hint)); |
| else |
| assertFalse("Unexpected supported hint [" + hint + "]", |
| query.getSupportedHints().contains(hint)); |
| } |
| |
| |
| } |