openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dianne Richards <diann...@gmail.com>
Subject Re: Change of MappingDefaults breaks OPENJPA_SEQUENCE_TABLE
Date Thu, 14 Jun 2012 17:21:27 GMT
Alexy - I've been asked to look into this. I don't have a lot of time now
to dig into it. But, a quick look makes me wonder if you could fix this by
using the DBDictionary property "schemaCase".  The default value is
"upper". I think you want to use "preserve". I see you've used a dictionary
property, so you should be able to figure this out. If that doesn't work,
I'll look into this further tomorrow.

Dianne

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

> It turned out the whole problem was not being able to find "version".
> I still don't understand why I didn't see that exception in the
> console, and I am quite sure it wasn't there (even with all log levels
> set to Trace). After failing to find it, OpenJPA didn't create any
> tables (including OPENJPA_SEQUENCE_TABLE), and OPENJPA_SEQUENCE_TABLE
> simply happened to be the first table it queried in my test.
>
> Stripping delimiters later was done for two reasons: 1) better looking
> generated SQL; 2) going back to @UniqueConstraint(columnNames = {
> "name", "version" })).
>
> What's the reasoning for DBIdentifierUtilImpl.makeIdentifierValid
> uppercasing all non-delimited identifiers, by the way?
>
> On Wed, Jun 13, 2012 at 11:26 PM, Kevin Sutter [via OpenJPA]
> <ml-node+s208410n7580279h98@n2.nabble.com> wrote:
> > 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
> > <[hidden email]>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.
> >>
> >
> >
> > ________________________________
> > If you reply to this email, your message will be added to the discussion
> > below:
> >
> http://openjpa.208410.n2.nabble.com/Change-of-MappingDefaults-breaks-OPENJPA-SEQUENCE-TABLE-tp7580246p7580279.html
> > To unsubscribe from Change of MappingDefaults breaks
> OPENJPA_SEQUENCE_TABLE,
> > click here.
> > NAML
>
>
> --
> View this message in context:
> http://openjpa.208410.n2.nabble.com/Change-of-MappingDefaults-breaks-OPENJPA-SEQUENCE-TABLE-tp7580246p7580281.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>



-- 
Thanks - Dianne

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