mirror of
https://github.com/apache/openjpa.git
synced 2025-02-20 17:05:15 +00:00
OPENJPA-2818 DBDictionary > delimitIdentifiers = true does not work (#69)
This commit is contained in:
parent
c1a6aa5a4e
commit
e3bb1f1657
0
openjpa-jdbc/nbproject/project.properties
Normal file
0
openjpa-jdbc/nbproject/project.properties
Normal file
@ -30,7 +30,7 @@ import org.apache.openjpa.lib.util.StringUtil;
|
||||
*/
|
||||
public class DBIdentifier extends IdentifierImpl implements Cloneable, Identifier, Serializable {
|
||||
|
||||
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
@ -754,16 +754,17 @@ public class DBIdentifier extends IdentifierImpl implements Cloneable, Identifie
|
||||
if (DBIdentifier.isNull(name)) {
|
||||
return name;
|
||||
}
|
||||
DBIdentifier sName = name.clone();
|
||||
if (sName.getNameInternal() == null) {
|
||||
return sName;
|
||||
if (name.getNameInternal() == null) {
|
||||
return name;
|
||||
}
|
||||
// Do not convert delimited names to upper case. They may have
|
||||
// been delimited to preserve case.
|
||||
if (force || !Normalizer.isDelimited(sName.getNameInternal())) {
|
||||
if (force || !Normalizer.isDelimited(name.getNameInternal())) {
|
||||
DBIdentifier sName = name.clone();
|
||||
sName.setNameInternal(sName.getNameInternal().toUpperCase());
|
||||
return sName;
|
||||
}
|
||||
return sName;
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -861,16 +862,35 @@ public class DBIdentifier extends IdentifierImpl implements Cloneable, Identifie
|
||||
if (DBIdentifier.isNull(name)) {
|
||||
return name;
|
||||
}
|
||||
DBIdentifier sName = name.clone();
|
||||
if (isEmpty(sName)) {
|
||||
return sName;
|
||||
if (!name.isDelimited()) {
|
||||
return name;
|
||||
}
|
||||
String strName = sName.getNameInternal();
|
||||
strName = Normalizer.removeDelimiters(strName);
|
||||
String strName = Normalizer.removeDelimiters(name.getNameInternal());
|
||||
DBIdentifier sName = name.clone();
|
||||
sName.setNameInternal(strName);
|
||||
return sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine {@link #removeDelimiters(org.apache.openjpa.jdbc.identifier.DBIdentifier) }
|
||||
* with {@link #toUpper(org.apache.openjpa.jdbc.identifier.DBIdentifier, boolean) }
|
||||
* in order to save allocations and CPU cycles.
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public static DBIdentifier removeDelimitersAndMakeUpper(DBIdentifier name) {
|
||||
if (DBIdentifier.isNull(name) || name.getNameInternal() == null) {
|
||||
return name;
|
||||
}
|
||||
if (!name.isDelimited()) {
|
||||
return toUpper(name, true);
|
||||
}
|
||||
String strName = Normalizer.removeDelimiters(name.getNameInternal());
|
||||
DBIdentifier sName = name.clone();
|
||||
sName.setNameInternal(strName.toUpperCase());
|
||||
return sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new delimiter with leading and trailing spaces removed.
|
||||
* @param name
|
||||
|
@ -40,6 +40,8 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
||||
@ -1030,10 +1032,7 @@ public class SchemaTool {
|
||||
continue;
|
||||
|
||||
if (dropColumn(cols[k])) {
|
||||
if (dbTable != null)
|
||||
dbTable.removeColumn(col);
|
||||
else
|
||||
_log.warn(_loc.get("drop-col", cols[k], tabs[j]));
|
||||
dbTable.removeColumn(col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ import org.apache.openjpa.lib.meta.SourceTracker;
|
||||
* @author Abe White
|
||||
* @author Stephen Kim
|
||||
*/
|
||||
|
||||
public class Table
|
||||
extends NameSet
|
||||
implements Comparable<Object>, SourceTracker {
|
||||
@ -45,6 +46,7 @@ public class Table
|
||||
private static final long serialVersionUID = 1L;
|
||||
private DBIdentifier _name = DBIdentifier.NULL;
|
||||
private DBIdentifier _schemaName = DBIdentifier.NULL;
|
||||
// all keys must be normalized with normalizeColumnKey
|
||||
private Map<DBIdentifier, Column> _colMap = null;
|
||||
private Map<DBIdentifier, Index> _idxMap = null;
|
||||
private Collection<ForeignKey> _fkList = null;
|
||||
@ -312,12 +314,20 @@ public class Table
|
||||
return _rels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of column names, used only for informative (error) messages.
|
||||
* @return
|
||||
*/
|
||||
public String[] getColumnNames() {
|
||||
if (_colMap == null) {
|
||||
return new String[0];
|
||||
}
|
||||
DBIdentifier[] sNames = _colMap.keySet().toArray(new DBIdentifier[_colMap.size()]);
|
||||
return DBIdentifier.toStringArray(sNames);
|
||||
return _colMap
|
||||
.values()
|
||||
.stream()
|
||||
.map(Column::getIdentifier)
|
||||
.map(DBIdentifier::getName)
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -329,10 +339,19 @@ public class Table
|
||||
return getColumn(DBIdentifier.newIdentifier(name, DBIdentifierType.COLUMN, true));
|
||||
}
|
||||
|
||||
public Column getColumn(DBIdentifier name) {
|
||||
private Column internalGetColumn(DBIdentifier name) {
|
||||
if (DBIdentifier.isNull(name) || _colMap == null)
|
||||
return null;
|
||||
return _colMap.get(DBIdentifier.toUpper(name));
|
||||
DBIdentifier key = normalizeColumnKey(name);
|
||||
return _colMap.get(key);
|
||||
}
|
||||
|
||||
public Column getColumn(DBIdentifier name) {
|
||||
return internalGetColumn(name);
|
||||
}
|
||||
|
||||
private static DBIdentifier normalizeColumnKey(DBIdentifier name) {
|
||||
return DBIdentifier.removeDelimitersAndMakeUpper(name);
|
||||
}
|
||||
|
||||
public Column getColumn(DBIdentifier name, boolean create) {
|
||||
@ -375,8 +394,7 @@ public class Table
|
||||
if (DBIdentifier.isNull(name) || _colMap == null) {
|
||||
return false;
|
||||
}
|
||||
DBIdentifier sName = DBIdentifier.toUpper(name);
|
||||
return _colMap.containsKey(sName);
|
||||
return _colMap.containsKey(normalizeColumnKey(name));
|
||||
}
|
||||
|
||||
public boolean containsColumn(Column col) {
|
||||
@ -414,8 +432,7 @@ public class Table
|
||||
}
|
||||
if (_colMap == null)
|
||||
_colMap = new LinkedHashMap<>();
|
||||
DBIdentifier sName = DBIdentifier.toUpper(name);
|
||||
_colMap.put(sName, col);
|
||||
_colMap.put(normalizeColumnKey(name), col);
|
||||
_cols = null;
|
||||
return col;
|
||||
}
|
||||
@ -440,8 +457,7 @@ public class Table
|
||||
col = new Column(validName, this);
|
||||
if (_colMap == null)
|
||||
_colMap = new LinkedHashMap<>();
|
||||
DBIdentifier sName = DBIdentifier.toUpper(name);
|
||||
_colMap.put(sName, col);
|
||||
_colMap.put(normalizeColumnKey(name), col);
|
||||
_cols = null;
|
||||
return col;
|
||||
}
|
||||
@ -469,7 +485,7 @@ public class Table
|
||||
if (col == null || _colMap == null)
|
||||
return false;
|
||||
|
||||
DBIdentifier sName = DBIdentifier.toUpper(col.getIdentifier());
|
||||
DBIdentifier sName = normalizeColumnKey(col.getIdentifier());
|
||||
Column cur = _colMap.get(sName);
|
||||
if (!col.equals(cur))
|
||||
return false;
|
||||
|
@ -217,7 +217,7 @@ public class DBDictionaryFactory {
|
||||
/**
|
||||
* Guess the dictionary class name to use based on the product string.
|
||||
*/
|
||||
private static String dictionaryClassForString(String prod, JDBCConfiguration conf) {
|
||||
static String dictionaryClassForString(String prod, JDBCConfiguration conf) {
|
||||
if (StringUtil.isEmpty(prod))
|
||||
return null;
|
||||
prod = prod.toLowerCase(Locale.ENGLISH);
|
||||
@ -270,6 +270,9 @@ public class DBDictionaryFactory {
|
||||
if (prod.indexOf("sapdb") != -1) {
|
||||
return dbdictionaryPlugin.unalias("maxdb");
|
||||
}
|
||||
if (prod.indexOf("herddb") != -1) {
|
||||
return dbdictionaryPlugin.unalias("herddb");
|
||||
}
|
||||
// test h2 in a special way, because there's a decent chance the string
|
||||
// h2 could appear in the URL of another database
|
||||
if (prod.indexOf("jdbc:h2:") != -1)
|
||||
|
@ -32,6 +32,8 @@ public class HerdDBDictionary
|
||||
supportsForeignKeys = false;
|
||||
supportsUniqueConstraints = false;
|
||||
supportsCascadeDeleteAction = false;
|
||||
schemaCase = SCHEMA_CASE_LOWER;
|
||||
delimitedCase = SCHEMA_CASE_PRESERVE;
|
||||
|
||||
// make OpenJPA escape everything, because Apache Calcite has a lot of reserved words, like 'User', 'Value'...
|
||||
setDelimitIdentifiers(true);
|
||||
|
@ -2154,7 +2154,7 @@ public class SelectImpl
|
||||
* Return the alias for the given table under the given joins.
|
||||
* NOTE: WE RELY ON THESE INDEXES BEING MONOTONICALLY INCREASING FROM 0
|
||||
*/
|
||||
private int getTableIndex(Table table, PathJoins pj, boolean create) {
|
||||
int getTableIndex(Table table, PathJoins pj, boolean create) {
|
||||
// if we have a from select, then there are no table aliases
|
||||
if (_from != null)
|
||||
return -1;
|
||||
@ -2699,7 +2699,7 @@ public class SelectImpl
|
||||
* Return the alias used to key on the column data, considering the
|
||||
* given joins.
|
||||
*/
|
||||
private String getColumnAlias(Column col, PathJoins pj) {
|
||||
String getColumnAlias(Column col, PathJoins pj) {
|
||||
String alias;
|
||||
if (_sel._from != null) {
|
||||
alias = SelectImpl.toAlias(_sel._from.getTableIndex
|
||||
@ -2711,7 +2711,7 @@ public class SelectImpl
|
||||
return alias + "_" + col;
|
||||
}
|
||||
alias = SelectImpl.toAlias(_sel.getTableIndex(col.getTable(), pj, false));
|
||||
return (alias == null) ? null : alias + "." + col;
|
||||
return (alias == null) ? null : alias + "." + _sel._dict.getNamingUtil().toDBName(col.toString());
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2020 Apache Software Foundation.
|
||||
*
|
||||
* Licensed 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.jdbc.sql;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
||||
import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
|
||||
|
||||
public class DBDictionaryFactoryTest {
|
||||
|
||||
@Test
|
||||
public void testDictionaryClassForString() {
|
||||
JDBCConfiguration conf = new JDBCConfigurationImpl();
|
||||
|
||||
String[] aliases = new String[]{
|
||||
"access", org.apache.openjpa.jdbc.sql.AccessDictionary.class.getName(),
|
||||
"db2", org.apache.openjpa.jdbc.sql.DB2Dictionary.class.getName(),
|
||||
"derby", org.apache.openjpa.jdbc.sql.DerbyDictionary.class.getName(),
|
||||
"empress", org.apache.openjpa.jdbc.sql.EmpressDictionary.class.getName(),
|
||||
"foxpro", org.apache.openjpa.jdbc.sql.FoxProDictionary.class.getName(),
|
||||
"h2", org.apache.openjpa.jdbc.sql.H2Dictionary.class.getName(),
|
||||
"hsql", org.apache.openjpa.jdbc.sql.HSQLDictionary.class.getName(),
|
||||
"informix", org.apache.openjpa.jdbc.sql.InformixDictionary.class.getName(),
|
||||
"ingres", org.apache.openjpa.jdbc.sql.IngresDictionary.class.getName(),
|
||||
"jdatastore", org.apache.openjpa.jdbc.sql.JDataStoreDictionary.class.getName(),
|
||||
"mariadb", org.apache.openjpa.jdbc.sql.MariaDBDictionary.class.getName(),
|
||||
"mysql", org.apache.openjpa.jdbc.sql.MySQLDictionary.class.getName(),
|
||||
"herddb", org.apache.openjpa.jdbc.sql.HerdDBDictionary.class.getName(),
|
||||
"oracle", org.apache.openjpa.jdbc.sql.OracleDictionary.class.getName(),
|
||||
"pointbase", org.apache.openjpa.jdbc.sql.PointbaseDictionary.class.getName(),
|
||||
"postgres", org.apache.openjpa.jdbc.sql.PostgresDictionary.class.getName(),
|
||||
"soliddb", org.apache.openjpa.jdbc.sql.SolidDBDictionary.class.getName(),
|
||||
"sqlserver", org.apache.openjpa.jdbc.sql.SQLServerDictionary.class.getName(),
|
||||
"sybase", org.apache.openjpa.jdbc.sql.SybaseDictionary.class.getName(),
|
||||
"maxdb", MaxDBDictionary.class.getName(),
|
||||
"jdbc:h2:", H2Dictionary.class.getName(),
|
||||
"h2 database", H2Dictionary.class.getName()
|
||||
};
|
||||
|
||||
for (int i = 0; i < aliases.length; i++) {
|
||||
String key = aliases[i++];
|
||||
String expected = aliases[i];
|
||||
assertEquals(expected, DBDictionaryFactory.dictionaryClassForString(key, conf));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.jdbc.sql;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
||||
import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
|
||||
import org.apache.openjpa.jdbc.identifier.DBIdentifier;
|
||||
import org.apache.openjpa.jdbc.schema.Column;
|
||||
import org.apache.openjpa.jdbc.schema.Table;
|
||||
import static org.apache.openjpa.jdbc.sql.Select.FROM_SELECT_ALIAS;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests about SelectImpl.
|
||||
*/
|
||||
public class TestSelectImpl {
|
||||
|
||||
@Test
|
||||
public void testSelectResultGetColumnAlias() {
|
||||
verifySelectResultGetColumnAlias(true, false, false, -1, "Col", 56, "t56.\"Col\"");
|
||||
verifySelectResultGetColumnAlias(false, false, false, -1, "Col", 18, "t18.Col");
|
||||
|
||||
// tests with additional select in from
|
||||
verifySelectResultGetColumnAlias(false, true /* fromSelect */, false, -1, "Col", 18, null);
|
||||
verifySelectResultGetColumnAlias(false, true, false, 92, "Col", 18, "t92_Col");
|
||||
verifySelectResultGetColumnAlias(false, true, true /* requiresAliasForSubselect */, 92, "Col", 18, FROM_SELECT_ALIAS + ".t92_Col");
|
||||
|
||||
verifySelectResultGetColumnAlias(true, true, false, -1, "Col", 18, null);
|
||||
verifySelectResultGetColumnAlias(true, true, false, 92, "Col", 18, "t92_Col");
|
||||
verifySelectResultGetColumnAlias(true, true, true /* requiresAliasForSubselect */, 92, "Col", 18, FROM_SELECT_ALIAS + ".t92_Col");
|
||||
}
|
||||
|
||||
private void verifySelectResultGetColumnAlias(boolean delimitIdentifiers, boolean fromSelect, boolean requiresAliasForSubselect,
|
||||
int fromSelectTableIndex, String colName, int tableIndex, String expected) {
|
||||
DBDictionary dict = new DBDictionary();
|
||||
dict.setDelimitIdentifiers(delimitIdentifiers);
|
||||
dict.requiresAliasForSubselect = requiresAliasForSubselect;
|
||||
dict.setSupportsDelimitedIdentifiers(delimitIdentifiers);
|
||||
dict.configureNamingRules();
|
||||
DBIdentifier columnName = DBIdentifier.newColumn(colName, false);
|
||||
|
||||
JDBCConfiguration conf = new JDBCConfigurationImpl();
|
||||
dict.setConfiguration(conf);
|
||||
conf.setDBDictionary(dict);
|
||||
SelectImpl selectImpl = new SelectImpl(conf) {
|
||||
@Override
|
||||
int getTableIndex(Table table, PathJoins pj, boolean create) {
|
||||
return tableIndex;
|
||||
}
|
||||
};
|
||||
Connection conn = null;
|
||||
Statement stmnt = null;
|
||||
ResultSet rs = null;
|
||||
SelectImpl.SelectResult result = new SelectImpl.SelectResult(conn, stmnt, rs, dict);
|
||||
result.setSelect(selectImpl);
|
||||
PathJoins pj = null;
|
||||
Column column = new Column(columnName, null);
|
||||
if (fromSelect) {
|
||||
SelectImpl fromSelectImpl = new SelectImpl(conf) {
|
||||
@Override
|
||||
int getTableIndex(Table table, PathJoins pj, boolean create) {
|
||||
return fromSelectTableIndex;
|
||||
}
|
||||
};
|
||||
selectImpl.setFromSelect(fromSelectImpl);
|
||||
} else {
|
||||
assertEquals(-1, fromSelectTableIndex);
|
||||
}
|
||||
String res = result.getColumnAlias(column, pj);
|
||||
assertEquals(expected, res);
|
||||
}
|
||||
}
|
@ -0,0 +1,536 @@
|
||||
/*
|
||||
* 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.jdbc.sql;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import org.apache.commons.dbcp2.BasicDataSource;
|
||||
import org.apache.derby.jdbc.EmbeddedDriver;
|
||||
import org.apache.openjpa.persistence.PersistenceProviderImpl;
|
||||
import org.apache.openjpa.persistence.PersistenceUnitInfoImpl;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.Statement;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.OffsetTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OneToOne;
|
||||
import org.apache.openjpa.persistence.PersistentCollection;
|
||||
|
||||
public class TestDelimitIdentifiers {
|
||||
|
||||
public static class LowercaseSchemaDerbyDBDictionary extends DerbyDictionary {
|
||||
|
||||
public LowercaseSchemaDerbyDBDictionary() {
|
||||
super();
|
||||
schemaCase = SCHEMA_CASE_LOWER;
|
||||
delimitedCase = SCHEMA_CASE_PRESERVE;
|
||||
setDelimitIdentifiers(true);
|
||||
setSupportsDelimitedIdentifiers(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelimitIdentifiers() throws SQLException {
|
||||
final PersistenceUnitInfoImpl persistenceUnitInfo = new PersistenceUnitInfoImpl();
|
||||
persistenceUnitInfo.setExcludeUnlistedClasses(true);
|
||||
persistenceUnitInfo.addManagedClassName(AllFieldTypes.class.getName());
|
||||
final BasicDataSource ds = new BasicDataSource();
|
||||
ds.setDriver(new EmbeddedDriver());
|
||||
ds.setUrl("jdbc:derby:memory:TestDelimitIdentifiers;create=true");
|
||||
persistenceUnitInfo.setNonJtaDataSource(ds);
|
||||
// reproducer for OPENJPA-2818 delimitIdentifiers=true,delimitedCase=lower,schemaCase=lower
|
||||
persistenceUnitInfo.setProperty("openjpa.jdbc.DBDictionary", LowercaseSchemaDerbyDBDictionary.class.getName());
|
||||
new PersistenceProviderImpl().generateSchema(persistenceUnitInfo, new HashMap<>());
|
||||
// try rebuild the schema
|
||||
new PersistenceProviderImpl().generateSchema(persistenceUnitInfo, new HashMap<>());
|
||||
|
||||
final Map<String, Collection<String>> columns = new HashMap<>();
|
||||
final Collection<String> createdTables = new HashSet<>();
|
||||
try (final Connection connection = ds.getConnection()) {
|
||||
try (final ResultSet tables = connection.getMetaData()
|
||||
.getTables(null, null, "TestDelimitIdentifiers$AllFieldTypes%", null)) {
|
||||
while (tables.next()) {
|
||||
final String table = tables.getString(3);
|
||||
createdTables.add(table);
|
||||
}
|
||||
}
|
||||
for (final String table : createdTables) {
|
||||
try (final Statement statement = connection.createStatement()) {
|
||||
try (final ResultSet rs = statement.executeQuery("select * from \"" + table + "\"")) {
|
||||
final ResultSetMetaData metaData = rs.getMetaData();
|
||||
final Set<String> columnNames = new HashSet<>();
|
||||
columns.put(table, columnNames);
|
||||
for (int i = 1; i <= metaData.getColumnCount(); i++) {
|
||||
columnNames.add(metaData.getColumnName(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final EntityManagerFactory entityManagerFactory = new PersistenceProviderImpl()
|
||||
.createContainerEntityManagerFactory(persistenceUnitInfo, new HashMap());
|
||||
try {
|
||||
final AllFieldTypes entity = new AllFieldTypes();
|
||||
final AllFieldTypes entity2 = new AllFieldTypes();
|
||||
{
|
||||
final EntityManager em = entityManagerFactory.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
try {
|
||||
em.persist(entity2);
|
||||
entity.setArrayOfStrings(new String[]{"a", "b"});
|
||||
entity.setStringField("foo");
|
||||
entity.setIntField(10);
|
||||
entity.setSelfOneOne(entity2);
|
||||
em.persist(entity);
|
||||
em.getTransaction().commit();
|
||||
} catch (final RuntimeException re) {
|
||||
if (em.getTransaction().isActive()) {
|
||||
em.getTransaction().rollback();
|
||||
}
|
||||
throw re;
|
||||
} finally {
|
||||
em.close();
|
||||
}
|
||||
}
|
||||
{
|
||||
final EntityManager em = entityManagerFactory.createEntityManager();
|
||||
try {
|
||||
assertEquals(2, em.createQuery("select x from TestDelimitIdentifiers$AllFieldTypes x").
|
||||
getResultList().size());
|
||||
assertEquals(1, em.createQuery("select x from TestDelimitIdentifiers$AllFieldTypes x where x.stringField = 'foo'").
|
||||
getResultList().size());
|
||||
assertEquals(0, em.createQuery("select x from TestDelimitIdentifiers$AllFieldTypes x where x.stringField = 'bar'").
|
||||
getResultList().size());
|
||||
assertEquals(1, em.createQuery("select x from TestDelimitIdentifiers$AllFieldTypes x where x.intField >= 10").
|
||||
getResultList().size());
|
||||
} finally {
|
||||
em.close();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
entityManagerFactory.close();
|
||||
}
|
||||
ds.close();
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class AllFieldTypes {
|
||||
|
||||
public enum EnumType {
|
||||
Value1, Value2
|
||||
};
|
||||
|
||||
// @Basic types
|
||||
private short shortField;
|
||||
private int intField;
|
||||
private boolean booleanField;
|
||||
private long longField;
|
||||
private float floatField;
|
||||
private char charField;
|
||||
private double doubleField;
|
||||
private byte byteField;
|
||||
private Short wShortField;
|
||||
private Integer wIntegerField;
|
||||
private Boolean wBooleanField;
|
||||
private Long wLongField;
|
||||
private Float wFloatField;
|
||||
private Character wCharacterField;
|
||||
private Double wDoubleField;
|
||||
private Byte wByteField;
|
||||
private BigInteger bigIntegerField;
|
||||
private BigDecimal bigDecimalField;
|
||||
private String stringField;
|
||||
private Date dateField;
|
||||
private Calendar calendarField;
|
||||
private java.sql.Date sqlDateField;
|
||||
private java.sql.Time sqlTimeField;
|
||||
private java.sql.Timestamp sqlTimestampField;
|
||||
private byte[] byteLob;
|
||||
private Byte[] wByteLob;
|
||||
private char[] charLob;
|
||||
private Character[] wCharacterLob;
|
||||
private EnumType enumField;
|
||||
private Serializable serializableField;
|
||||
|
||||
// Additional types
|
||||
private Set<String> setOfStrings = new HashSet<>();
|
||||
private String[] arrayOfStrings;
|
||||
|
||||
@PersistentCollection
|
||||
private int[] arrayOfInts;
|
||||
|
||||
// one-to-one and one-to-many relations to self
|
||||
@OneToOne
|
||||
private AllFieldTypes selfOneOne;
|
||||
@OneToMany
|
||||
private List<AllFieldTypes> selfOneMany = new ArrayList<>();
|
||||
|
||||
// Java8 DateTime types which are required by the JPA-2.2 spec
|
||||
private LocalDate localDateField;
|
||||
private LocalTime localTimeField;
|
||||
private LocalDateTime localDateTimeField;
|
||||
private OffsetTime offsetTimeField;
|
||||
private OffsetDateTime offsetDateTimeField;
|
||||
|
||||
public void setShortField(short shortField) {
|
||||
this.shortField = shortField;
|
||||
}
|
||||
|
||||
public short getShortField() {
|
||||
return this.shortField;
|
||||
}
|
||||
|
||||
public void setIntField(int intField) {
|
||||
this.intField = intField;
|
||||
}
|
||||
|
||||
public int getIntField() {
|
||||
return this.intField;
|
||||
}
|
||||
|
||||
public void setBooleanField(boolean booleanField) {
|
||||
this.booleanField = booleanField;
|
||||
}
|
||||
|
||||
public boolean getBooleanField() {
|
||||
return this.booleanField;
|
||||
}
|
||||
|
||||
public void setLongField(long longField) {
|
||||
this.longField = longField;
|
||||
}
|
||||
|
||||
public long getLongField() {
|
||||
return this.longField;
|
||||
}
|
||||
|
||||
public void setFloatField(float floatField) {
|
||||
this.floatField = floatField;
|
||||
}
|
||||
|
||||
public float getFloatField() {
|
||||
return this.floatField;
|
||||
}
|
||||
|
||||
public void setCharField(char charField) {
|
||||
this.charField = charField;
|
||||
}
|
||||
|
||||
public char getCharField() {
|
||||
return this.charField;
|
||||
}
|
||||
|
||||
public void setDoubleField(double doubleField) {
|
||||
this.doubleField = doubleField;
|
||||
}
|
||||
|
||||
public double getDoubleField() {
|
||||
return this.doubleField;
|
||||
}
|
||||
|
||||
public void setByteField(byte byteField) {
|
||||
this.byteField = byteField;
|
||||
}
|
||||
|
||||
public byte getByteField() {
|
||||
return this.byteField;
|
||||
}
|
||||
|
||||
public void setStringField(String stringField) {
|
||||
this.stringField = stringField;
|
||||
}
|
||||
|
||||
public String getStringField() {
|
||||
return this.stringField;
|
||||
}
|
||||
|
||||
public void setDateField(Date dateField) {
|
||||
this.dateField = dateField;
|
||||
}
|
||||
|
||||
public Date getDateField() {
|
||||
return this.dateField;
|
||||
}
|
||||
|
||||
public void setSetOfStrings(Set<String> setOfStrings) {
|
||||
this.setOfStrings = setOfStrings;
|
||||
}
|
||||
|
||||
public Set<String> getSetOfStrings() {
|
||||
return this.setOfStrings;
|
||||
}
|
||||
|
||||
public void setArrayOfStrings(String[] arrayOfStrings) {
|
||||
this.arrayOfStrings = arrayOfStrings;
|
||||
}
|
||||
|
||||
public String[] getArrayOfStrings() {
|
||||
return this.arrayOfStrings;
|
||||
}
|
||||
|
||||
public void setArrayOfInts(int[] arrayOfInts) {
|
||||
this.arrayOfInts = arrayOfInts;
|
||||
}
|
||||
|
||||
public int[] getArrayOfInts() {
|
||||
return arrayOfInts;
|
||||
}
|
||||
|
||||
public BigDecimal getBigDecimalField() {
|
||||
return bigDecimalField;
|
||||
}
|
||||
|
||||
public void setBigDecimalField(BigDecimal bigDecimalField) {
|
||||
this.bigDecimalField = bigDecimalField;
|
||||
}
|
||||
|
||||
public BigInteger getBigIntegerField() {
|
||||
return bigIntegerField;
|
||||
}
|
||||
|
||||
public void setBigIntegerField(BigInteger bigIntegerField) {
|
||||
this.bigIntegerField = bigIntegerField;
|
||||
}
|
||||
|
||||
public byte[] getByteLob() {
|
||||
return byteLob;
|
||||
}
|
||||
|
||||
public void setByteLob(byte[] byteLob) {
|
||||
this.byteLob = byteLob;
|
||||
}
|
||||
|
||||
public Calendar getCalendarField() {
|
||||
return calendarField;
|
||||
}
|
||||
|
||||
public void setCalendarField(Calendar calendarField) {
|
||||
this.calendarField = calendarField;
|
||||
}
|
||||
|
||||
public char[] getCharLob() {
|
||||
return charLob;
|
||||
}
|
||||
|
||||
public void setCharLob(char[] charLob) {
|
||||
this.charLob = charLob;
|
||||
}
|
||||
|
||||
public EnumType getEnumField() {
|
||||
return enumField;
|
||||
}
|
||||
|
||||
public void setEnumField(EnumType enumField) {
|
||||
this.enumField = enumField;
|
||||
}
|
||||
|
||||
public Serializable getSerializableField() {
|
||||
return serializableField;
|
||||
}
|
||||
|
||||
public void setSerializableField(Serializable serializableField) {
|
||||
this.serializableField = serializableField;
|
||||
}
|
||||
|
||||
public java.sql.Date getSqlDateField() {
|
||||
return sqlDateField;
|
||||
}
|
||||
|
||||
public void setSqlDateField(java.sql.Date sqlDateField) {
|
||||
this.sqlDateField = sqlDateField;
|
||||
}
|
||||
|
||||
public java.sql.Time getSqlTimeField() {
|
||||
return sqlTimeField;
|
||||
}
|
||||
|
||||
public void setSqlTimeField(java.sql.Time sqlTimeField) {
|
||||
this.sqlTimeField = sqlTimeField;
|
||||
}
|
||||
|
||||
public java.sql.Timestamp getSqlTimestampField() {
|
||||
return sqlTimestampField;
|
||||
}
|
||||
|
||||
public void setSqlTimestampField(java.sql.Timestamp sqlTimestampField) {
|
||||
this.sqlTimestampField = sqlTimestampField;
|
||||
}
|
||||
|
||||
public Boolean getWBooleanField() {
|
||||
return wBooleanField;
|
||||
}
|
||||
|
||||
public void setWBooleanField(Boolean booleanField) {
|
||||
wBooleanField = booleanField;
|
||||
}
|
||||
|
||||
public Byte getWByteField() {
|
||||
return wByteField;
|
||||
}
|
||||
|
||||
public void setWByteField(Byte byteField) {
|
||||
wByteField = byteField;
|
||||
}
|
||||
|
||||
public Byte[] getWByteLob() {
|
||||
return wByteLob;
|
||||
}
|
||||
|
||||
public void setWByteLob(Byte[] byteLob) {
|
||||
wByteLob = byteLob;
|
||||
}
|
||||
|
||||
public Character getWCharacterField() {
|
||||
return wCharacterField;
|
||||
}
|
||||
|
||||
public void setWCharacterField(Character characterField) {
|
||||
wCharacterField = characterField;
|
||||
}
|
||||
|
||||
public Character[] getWCharacterLob() {
|
||||
return wCharacterLob;
|
||||
}
|
||||
|
||||
public void setWCharacterLob(Character[] characterLob) {
|
||||
wCharacterLob = characterLob;
|
||||
}
|
||||
|
||||
public Double getWDoubleField() {
|
||||
return wDoubleField;
|
||||
}
|
||||
|
||||
public void setWDoubleField(Double doubleField) {
|
||||
wDoubleField = doubleField;
|
||||
}
|
||||
|
||||
public Float getWFloatField() {
|
||||
return wFloatField;
|
||||
}
|
||||
|
||||
public void setWFloatField(Float floatField) {
|
||||
wFloatField = floatField;
|
||||
}
|
||||
|
||||
public Integer getWIntegerField() {
|
||||
return wIntegerField;
|
||||
}
|
||||
|
||||
public void setWIntegerField(Integer integerField) {
|
||||
wIntegerField = integerField;
|
||||
}
|
||||
|
||||
public Long getWLongField() {
|
||||
return wLongField;
|
||||
}
|
||||
|
||||
public void setWLongField(Long longField) {
|
||||
wLongField = longField;
|
||||
}
|
||||
|
||||
public Short getWShortField() {
|
||||
return wShortField;
|
||||
}
|
||||
|
||||
public void setWShortField(Short shortField) {
|
||||
wShortField = shortField;
|
||||
}
|
||||
|
||||
public AllFieldTypes getSelfOneOne() {
|
||||
return selfOneOne;
|
||||
}
|
||||
|
||||
public void setSelfOneOne(AllFieldTypes selfOneOne) {
|
||||
this.selfOneOne = selfOneOne;
|
||||
}
|
||||
|
||||
public List<AllFieldTypes> getSelfOneMany() {
|
||||
return selfOneMany;
|
||||
}
|
||||
|
||||
public void setSelfOneMany(List<AllFieldTypes> selfOneMany) {
|
||||
this.selfOneMany = selfOneMany;
|
||||
}
|
||||
|
||||
public LocalDate getLocalDateField() {
|
||||
return localDateField;
|
||||
}
|
||||
|
||||
public void setLocalDateField(LocalDate localDateField) {
|
||||
this.localDateField = localDateField;
|
||||
}
|
||||
|
||||
public LocalTime getLocalTimeField() {
|
||||
return localTimeField;
|
||||
}
|
||||
|
||||
public void setLocalTimeField(LocalTime localTimeField) {
|
||||
this.localTimeField = localTimeField;
|
||||
}
|
||||
|
||||
public LocalDateTime getLocalDateTimeField() {
|
||||
return localDateTimeField;
|
||||
}
|
||||
|
||||
public void setLocalDateTimeField(LocalDateTime localDateTimeField) {
|
||||
this.localDateTimeField = localDateTimeField;
|
||||
}
|
||||
|
||||
public OffsetTime getOffsetTimeField() {
|
||||
return offsetTimeField;
|
||||
}
|
||||
|
||||
public void setOffsetTimeField(OffsetTime offsetTimeField) {
|
||||
this.offsetTimeField = offsetTimeField;
|
||||
}
|
||||
|
||||
public OffsetDateTime getOffsetDateTimeField() {
|
||||
return offsetDateTimeField;
|
||||
}
|
||||
|
||||
public void setOffsetDateTimeField(OffsetDateTime offsetDateTimeField) {
|
||||
this.offsetDateTimeField = offsetDateTimeField;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user