openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Kevin Sutter <kwsut...@gmail.com>
Subject Re: Change of MappingDefaults breaks OPENJPA_SEQUENCE_TABLE
Date Wed, 13 Jun 2012 18:35:21 GMT
Thanks, Alexey, for your debugging efforts.  This seems to indicate an
issue with our delimited identifier support.  One clarification, when you
said that changing the UniqueConstraint fixed the problem, did you mean
just the JUnit exception that you posted about not able to find "version",
or did it fix both of your issues?

@UniqueConstraint(columnNames = { "name", "\"version\"" }))

I'm assuming it only resolved the JUnit exception since you still had to
hack another solution with stripping the delimiters...

Thanks,
Kevin

On Wed, Jun 13, 2012 at 3:00 AM, Alexey Romanov
<alexey.v.romanov@gmail.com>wrote:

> 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.
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message