/*
* 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.order;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.lib.meta.MetaDataSerializer;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.persistence.ArgumentException;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.apache.openjpa.persistence.jdbc.XMLPersistenceMappingParser;
import org.apache.openjpa.persistence.jdbc.XMLPersistenceMappingSerializer;
import org.apache.openjpa.persistence.test.AbstractCachedEMFTestCase;
public class TestOrderColumnXML extends AbstractCachedEMFTestCase {
/*
* Validates the use of the nullable attribute on OrderColumn through
* an entity defined in orm.xml
*/
public void testOrderColumnNullableFalse() {
OpenJPAEntityManagerFactorySPI emf1 =
(OpenJPAEntityManagerFactorySPI)OpenJPAPersistence.
createEntityManagerFactory("BaseNoNullTest",
"org/apache/openjpa/persistence/jdbc/order/" +
"order-persistence-4.xml");
OpenJPAConfiguration conf = emf1.getConfiguration();
MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
// Force entity resolution
repos.getMetaData(BaseTestEntity2.class, null, true);
OpenJPAEntityManagerSPI em = emf1.createEntityManager();
validateOrderColumnNullable(emf1, BaseTestEntity2.class,
"one2Melems", false);
validateOrderColumnNullable(emf1, BaseTestEntity2.class,
"collelems", false);
validateOrderColumnNullable(emf1, BaseTestEntity2.class,
"m2melems", false);
em.close();
try {
if (emf1 != null)
cleanupEMF(emf1);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
}
/*
* Validates the use of the columnDefinition attribute on OrderColumn.
*/
public void testOrderColumnColumnDefinition() {
OpenJPAEntityManagerFactorySPI emf1 =
(OpenJPAEntityManagerFactorySPI)OpenJPAPersistence.
createEntityManagerFactory("ColDefTest",
"org/apache/openjpa/persistence/jdbc/order/" +
"order-persistence-2.xml");
// Create the EM. This will spark the mapping tool.
OpenJPAEntityManagerSPI em = emf1.createEntityManager();
//
// Create a collection using a custom column definition
validateOrderColumnDef(emf1, ColDefTestEntity.class,
"one2Mcoldef", "INTEGER");
validateOrderColumnDef(emf1, ColDefTestEntity.class,
"collcoldef", "INTEGER");
validateOrderColumnDef(emf1, ColDefTestEntity.class,
"m2mcoldef", "INTEGER");
// Add and query some values
ColDefTestEntity cdent = new ColDefTestEntity();
ColDefTestElement cdel1 = new ColDefTestElement("Element1");
ColDefTestElement cdel2 = new ColDefTestElement("Element2");
ColDefTestElement cdel3 = new ColDefTestElement("Element3");
List<ColDefTestElement> one2Mcoldef =
new ArrayList<ColDefTestElement>();
one2Mcoldef.add(cdel3);
one2Mcoldef.add(cdel2);
one2Mcoldef.add(cdel1);
cdent.setOne2Mcoldef(one2Mcoldef);
Set<ColDefTestElement> collcoldef =
new LinkedHashSet<ColDefTestElement>();
collcoldef.add(cdel1);
collcoldef.add(cdel2);
collcoldef.add(cdel3);
cdent.setCollcoldef(collcoldef);
List<ColDefTestElement> m2mcoldef = new ArrayList<ColDefTestElement>();
m2mcoldef.add(cdel2);
m2mcoldef.add(cdel1);
m2mcoldef.add(cdel3);
cdent.setM2mcoldef(m2mcoldef);
em.getTransaction().begin();
em.persist(cdent);
em.getTransaction().commit();
em.close();
try {
if (emf1 != null)
cleanupEMF(emf1);
} catch (Exception e) {
fail(e.getMessage());
}
}
/**
* Validates the use of the table attribute defined in XML
*/
public void testOrderColumnTableXML() {
OpenJPAEntityManagerFactorySPI emf1 =
(OpenJPAEntityManagerFactorySPI)OpenJPAPersistence.
createEntityManagerFactory("TableTest",
"org/apache/openjpa/persistence/jdbc/order/" +
"order-persistence-5.xml");
OpenJPAEntityManagerSPI em = emf1.createEntityManager();
validateOrderColumnTable(emf1, BaseTestEntity3.class, "one2Melems",
"xml_o2m_table", "one2MOrder");
validateOrderColumnTable(emf1, BaseTestEntity3.class, "m2melems",
"xml_m2m_table", "m2morder");
validateOrderColumnTable(emf1, BaseTestEntity3.class, "collelems",
"xml_coll_table", "collelems_ORDER");
em.close();
try {
if (emf1 != null)
cleanupEMF(emf1);
} catch (Exception e) {
fail(e.getMessage());
}
}
/*
* Validates OrderBy and OrderColumn should not be specified together per
* the JPA 2.0 spec.
*/
public void testOrderColumnOrderBy() {
OpenJPAEntityManagerFactorySPI emf1 = null;
OpenJPAEntityManagerSPI em = null;
try {
emf1 = (OpenJPAEntityManagerFactorySPI)OpenJPAPersistence.
createEntityManagerFactory("ObOcTest",
"org/apache/openjpa/persistence/jdbc/order/" +
"order-persistence-3.xml");
em = emf1.createEntityManager();
ObOcEntity ent = new ObOcEntity();
List<Integer> intList = new ArrayList<Integer>();
intList.add(new Integer(10));
intList.add(new Integer(20));
ent.setIntList(intList);
em.getTransaction().begin();
em.persist(intList);
em.getTransaction().commit();
em.close();
em = null;
fail("An exception should have been thrown.");
} catch (Exception e) {
assertException(e, ArgumentException.class);
} finally {
if (em != null)
em.close();
}
try {
if (emf1 != null)
cleanupEMF(emf1);
} catch (Exception e) {
fail(e.getMessage());
}
}
public void testOrderColumnMetaDataSerialization()
throws Exception {
OpenJPAEntityManagerFactorySPI emf1 =
(OpenJPAEntityManagerFactorySPI)OpenJPAPersistence.
createEntityManagerFactory("BaseTest",
"org/apache/openjpa/persistence/jdbc/order/" +
"order-persistence.xml");
OpenJPAConfiguration conf = emf1.getConfiguration();
MetaDataRepository repos = conf.newMetaDataRepositoryInstance();
// Force entity resolution
repos.getMetaData(BaseTestEntity1.class, null, true);
XMLPersistenceMappingSerializer ser =
new XMLPersistenceMappingSerializer((JDBCConfiguration)conf);
ser.addAll(repos);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ser.serialize(new OutputStreamWriter(out), MetaDataSerializer.PRETTY);
byte[] bytes = out.toByteArray();
XMLPersistenceMappingParser parser =
new XMLPersistenceMappingParser((JDBCConfiguration)conf);
parser.parse(new InputStreamReader
(new ByteArrayInputStream(bytes)), "bytes");
MetaDataRepository mdr2 = parser.getRepository();
ClassMetaData _entityMeta2 =
mdr2.getMetaData(BaseTestEntity1.class, null, true);
// Assert metadata is populated correctly
FieldMapping fm = (FieldMapping)_entityMeta2.getField("one2Melems");
Column oc = fm.getOrderColumn();
assertNotNull(oc);
assertEquals(oc.getName(),"one2MOrder");
fm = (FieldMapping)_entityMeta2.getField("m2melems");
oc = fm.getOrderColumn();
assertNotNull(oc);
assertEquals(oc.getName(),"m2morder");
fm = (FieldMapping)_entityMeta2.getField("collelems");
oc = fm.getOrderColumn();
assertNotNull(oc);
assertEquals(oc.getName(),"collelems_ORDER");
try {
if (emf1 != null)
cleanupEMF(emf1);
} catch (Exception e) {
fail(e.getMessage());
}
}
private Column getOrderColumn(OpenJPAEntityManagerFactorySPI emf1,
Class clazz, String fieldName) {
JDBCConfiguration conf = (JDBCConfiguration) emf1.getConfiguration();
ClassMapping cls = conf.getMappingRepositoryInstance().
getMapping(clazz, null, true);
FieldMapping fm = cls.getFieldMapping(fieldName);
Column oc = fm.getOrderColumn();
assertNotNull(oc);
return oc;
}
private void validateOrderColumnTable(
OpenJPAEntityManagerFactorySPI emf1,
Class clazz, String fieldName, String tableName,
String columnName) {
Column oc = getOrderColumn(emf1, clazz, fieldName);
// Verify the oc has the correct table name
assertTrue(oc.getTableName().equalsIgnoreCase(tableName));
// Verify the table exists in the db
assertTrue(tableAndColumnExists(emf1, null, tableName, null,
columnName));
}
private void validateOrderColumnDef(
OpenJPAEntityManagerFactorySPI emf1, Class clazz, String fieldName,
String type) {
Column oc = getOrderColumn(emf1, clazz, fieldName);
assertEquals(type, oc.getTypeName());
}
private void validateOrderColumnNullable(
OpenJPAEntityManagerFactorySPI emf1, Class clazz, String fieldName,
boolean nullable) {
Column oc = getOrderColumn(emf1, clazz, fieldName);
assertEquals(nullable, !oc.isNotNull());
}
/**
* Method to verify a table was created for the given name and schema
*/
private boolean tableAndColumnExists(OpenJPAEntityManagerFactorySPI emf1,
OpenJPAEntityManagerSPI em, String tableName, String schemaName,
String columnName) {
JDBCConfiguration conf = (JDBCConfiguration) emf1.getConfiguration();
DBDictionary dict = conf.getDBDictionaryInstance();
OpenJPAEntityManagerSPI em1 = em;
// If no em supplied, create one
if (em1 == null) {
em1 = emf1.createEntityManager();
}
Connection conn = (Connection)em1.getConnection();
try {
DatabaseMetaData dbmd = conn.getMetaData();
// (meta, catalog, schemaName, tableName, conn)
Column[] cols = dict.getColumns(dbmd, null, null,
tableName, columnName, conn);
if (cols != null && cols.length == 1) {
Column col = cols[0];
String colName = col.getName();
if (col.getTableName().equalsIgnoreCase(tableName) &&
(schemaName == null ||
col.getSchemaName().equalsIgnoreCase(schemaName)) &&
colName.equalsIgnoreCase(columnName))
return true;
}
} catch (Throwable e) {
fail("Unable to get column information.");
} finally {
if (em == null) {
em1.close();
}
}
return false;
}
/**
* Closes a specific entity manager factory and cleans up
* associated tables.
*/
private void cleanupEMF(OpenJPAEntityManagerFactorySPI emf1)
throws Exception {
if (emf1 == null)
return;
try {
clear(emf1);
} catch (Exception e) {
// if a test failed, swallow any exceptions that happen
// during tear-down, as these just mask the original problem.
if (testResult.wasSuccessful())
throw e;
} finally {
closeEMF(emf1);
}
}
}