So the problem is that if I don't delimit column names, DBIdentifierUtilImpl.makeIdentifierValid (called from dict.getValidColumnName) will convert them to upper case, whether I want it or not. The ugly solution I came up with is to delimit them and strip the delimiters later. Unfortunately, this leads to code duplication :( This is what I have at the moment:
package ru.focusmedia.odp.server.datastore.jpa.impl; import org.apache.openjpa.jdbc.identifier.DBIdentifier; import org.apache.openjpa.jdbc.identifier.Normalizer; import org.apache.openjpa.jdbc.meta.FieldMapping; import org.apache.openjpa.jdbc.meta.ValueMapping; import org.apache.openjpa.jdbc.schema.Column; import org.apache.openjpa.jdbc.schema.Table; import org.apache.openjpa.meta.JavaTypes; import org.apache.openjpa.persistence.jdbc.PersistenceMappingDefaults; public class ImprovedMappingDefaults extends PersistenceMappingDefaults { @Override protected void correctName(Table table, Column col) { String originalName = col.getIdentifier().getName(); boolean wasOriginallyDelimited = Normalizer.isDelimited(originalName); DBIdentifier name = DBIdentifier.newColumn(originalName, !wasOriginallyDelimited); DBIdentifier validName = dict.getValidColumnName(name, table); validName = addUnderscores(validName, wasOriginallyDelimited); col.setIdentifier(validName); table.addCorrectedColumnName(validName, true); } @Override public void populateJoinColumn(FieldMapping fm, Table local, Table foreign, Column col, Object target, int pos, int cols) { if (!(target instanceof Column)) return; // if this is a bidi relation, prefix with inverse field name, else // prefix with owning entity name FieldMapping[] inverses = fm.getInverseMappings(); DBIdentifier sName = DBIdentifier.NULL; String originalName = inverses.length > 0 ? inverses[0].getName() : fm .getDefiningMapping().getTypeAlias(); boolean wasOriginallyDelimited = Normalizer.isDelimited(originalName); sName = DBIdentifier.newColumn(originalName, !wasOriginallyDelimited); DBIdentifier targetName = ((Column) target).getIdentifier(); DBIdentifier tempName = DBIdentifier.NULL; if ((sName.length() + targetName.length()) >= dict.maxColumnNameLength) { tempName = DBIdentifier.truncate(sName, dict.maxColumnNameLength - targetName.length() - 1); } // suffix with '_' + target column if (DBIdentifier.isNull(tempName)) tempName = sName; sName = DBIdentifier.combine(tempName, targetName.getName()); sName = dict.getValidColumnName(sName, foreign); sName = addUnderscores(sName, wasOriginallyDelimited); col.setIdentifier(sName); } @Override public void populateForeignKeyColumn(ValueMapping vm, DBIdentifier sName, Table local, Table foreign, Column col, Object target, boolean inverse, int pos, int cols) { boolean elem = vm == vm.getFieldMapping().getElement() && vm.getFieldMapping().getTypeCode() != JavaTypes.MAP; // if this is a non-inverse collection element key, it must be in // a join table: if we're not prepending the field name, leave the // default if (!getPrependFieldNameToJoinTableInverseJoinColumns() && !inverse && elem) return; // otherwise jpa always uses <field>_<pkcol> for column name, even // when only one col if (target instanceof Column) { if (DBIdentifier.isNull(sName)) { sName = col.getIdentifier(); } else { String originalName = elem ? vm.getFieldMapping().getName() : Normalizer.removeHungarianNotation(sName.getName()); boolean wasOriginallyDelimited = Normalizer.isDelimited(originalName); sName = DBIdentifier.newColumn(originalName, !wasOriginallyDelimited); sName = DBIdentifier.combine(sName, ((Column)target).getIdentifier().getName()); // No need to check for uniqueness. sName = dict.getValidColumnName(sName, local, false); sName = addUnderscores(sName, wasOriginallyDelimited); } col.setIdentifier(sName); } } private DBIdentifier addUnderscores(DBIdentifier sName, boolean wasOriginallyDelimited) { String nameWithUnderscores = addUnderscores(sName.getName()); if (!wasOriginallyDelimited) { nameWithUnderscores = Normalizer .removeDelimiters(nameWithUnderscores); } sName = DBIdentifier.newColumn(nameWithUnderscores, false); return sName; } // taken from Hibernate's ImprovedNamingStrategy private static String addUnderscores(String name) { StringBuilder buf = new StringBuilder(name.replace('.', '_')); for (int i = 1; i < buf.length() - 1; i++) { if (Character.isLowerCase(buf.charAt(i - 1)) && Character.isUpperCase(buf.charAt(i)) && Character.isLowerCase(buf.charAt(i + 1))) { buf.insert(i++, '_'); } } return buf.toString().toLowerCase(); } } -- View this message in context: http://openjpa.208410.n2.nabble.com/Change-of-MappingDefaults-breaks-OPENJPA-SEQUENCE-TABLE-tp7580246p7580270.html Sent from the OpenJPA Users mailing list archive at Nabble.com.