/*
* 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.jdbc.mapping;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.apache.openjpa.kernel.QueryLanguages;
import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.Entity1;
import org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.Entity2;
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
public class TestNativeQueries extends SingleEMFTestCase {
private static final String TABLE_NAME = "entity_1";
private static final String TABLE_NAME_2 = "ENTITY2";
private static final String CONST_NAME = "testSimple";
private static final int CONST_INT = 42;
private EntityManager em;
public void setUp() {
super.setUp(CLEAR_TABLES, Entity1.class, Entity2.class);
em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(new Entity1(1, CONST_NAME, CONST_INT));
em.persist(new Entity1(2, CONST_NAME+" Changed", CONST_INT+1));
em.persist(new Entity1(3, CONST_NAME+" Changed 2", CONST_INT+2));
em.getTransaction().commit();
em.getTransaction().begin();
}
public void testNoParameter() {
String sql = "SELECT * FROM " + TABLE_NAME;
assertSize(3, em.createNativeQuery(sql, Entity1.class).getResultList());
}
public void testLiteral() {
String sql = "SELECT * FROM " + TABLE_NAME
+ " WHERE INTFIELD = " + CONST_INT;
assertSize(1, em.createNativeQuery(sql, Entity1.class).getResultList());
}
public void testParameter() {
String sql = "SELECT * FROM " + TABLE_NAME
+ " WHERE INTFIELD = ?1";
assertSize(1, em.createNativeQuery(sql, Entity1.class)
.setParameter(1, CONST_INT)
.getResultList());
}
public void testOutOfOrderParameter() {
String sql = "SELECT * FROM " + TABLE_NAME
+ " WHERE INTFIELD = ?2 AND STRINGFIELD = ?1";
assertSize(1, em.createNativeQuery(sql, Entity1.class)
.setParameter(2, CONST_INT)
.setParameter(1, CONST_NAME)
.getResultList());
}
public void testDuplicateParameter() {
String sql = "SELECT * FROM " + TABLE_NAME
+ " WHERE INTFIELD = ?1 AND INTFIELD = ?1";
assertSize(1, em.createNativeQuery(sql, Entity1.class)
.setParameter(1, CONST_INT)
.getResultList());
}
public void testDifferentParameterToSameField() {
String sql = "SELECT * FROM " + TABLE_NAME
+ " WHERE INTFIELD = ?1 OR INTFIELD = ?2";
assertSize(2, em.createNativeQuery(sql, Entity1.class)
.setParameter(1, CONST_INT)
.setParameter(2, CONST_INT+1)
.getResultList());
}
public void testQuoteParameterIgnored() {
String sql = "SELECT * FROM " + TABLE_NAME
+ " WHERE INTFIELD = ?1 OR STRINGFIELD = '?2'";
assertSize(1, em.createNativeQuery(sql, Entity1.class)
.setParameter(1, CONST_INT)
.getResultList());
}
public void testParameterMarkerWithoutSpaces() {
String sql = "SELECT * FROM " + TABLE_NAME
+ " WHERE INTFIELD=?1";
assertSize(1, em.createNativeQuery(sql, Entity1.class)
.setParameter(1, CONST_INT)
.getResultList());
}
public void testZeroBasedParameterSettingFails() {
try {
String sql = "SELECT * FROM " + TABLE_NAME
+ " WHERE INTFIELD = ?1";
em.createNativeQuery(sql, Entity1.class)
.setParameter(0, 12);
fail("Expected to fail with 0 parameter index");
} catch (Exception e) {
// as expected
}
}
public void testNamedParameterFails() {
/*
* Named parameters are not supported according to Section 3.6.8 of
* JPA 2.0 (pp 100) public draft Oct 31, 2008:
* "The use of named parameters is not defined for native queries.
* Only positional parameter binding for SQL queries may be used by
* portable applications."
*/
String sql = "SELECT * FROM " + TABLE_NAME + " WHERE INTFIELD = :p";
try {
em.createNativeQuery (sql, Entity1.class)
.setParameter ("p", 12);
fail("Expected to fail with NAMED parameter");
} catch (IllegalArgumentException ex) {
// good
}
}
public void testHintsAreProcessed() {
Query q = em.createNamedQuery("SQLWithHints");
assertEquals(QueryLanguages.LANG_SQL,
OpenJPAPersistence.cast(q).getLanguage());
String hintKey = "XYZ";
assertTrue(q.getHints().containsKey(hintKey));
assertEquals("abc", q.getHints().get(hintKey));
}
public void testNullResult(){
String sql = "SELECT max(pk) FROM " + TABLE_NAME_2+ "";
assertNull(em.createNativeQuery(sql, Long.class).getSingleResult());
}
public void assertSize(int num, List l) {
assertNotNull(l);
assertEquals(num, l.size());
}
}