Customize JPA field name mapping using EclipseLink

六月ゝ 毕业季﹏ 提交于 2019-12-01 18:16:57

Instead of

directMapping.setFieldName(nameMap.get(oldFieldName ));

try:

directMapping.getField().resetQualifiedName(nameMap.get(oldFieldName));

This does the trick for me under EclipseLink 2.5.0

Antonio Maria Sanchez Berrocal

Perhaps you could use my session customizer. It converts table names, and field names to Camel case. It supports inheritance and embeded entities. I tested for 2 years, and I got no issues or side effects. Enjoy it!

import java.sql.SQLException;
import java.util.Locale;
import java.util.Vector;
import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.tools.schemaframework.IndexDefinition;

public class CamelNamingStrategy implements SessionCustomizer {
    public static String unqualify(final String qualifiedName) {
        int loc = qualifiedName.lastIndexOf(".");
        return loc < 0 ? qualifiedName : qualifiedName.substring(qualifiedName.lastIndexOf(".") + 1);
    }

    @Override
    public void customize(final Session session) throws SQLException {
        for (ClassDescriptor descriptor : session.getDescriptors().values()) {
            if (!descriptor.getTables().isEmpty()) {
                // Take table name from @Table if exists
                String tableName = null;
                if (descriptor.getAlias().equalsIgnoreCase(descriptor.getTableName())) {
                    tableName = unqualify(descriptor.getJavaClassName());
                } else {
                    tableName = descriptor.getTableName();
                }
                tableName = camelCaseToUnderscore(tableName);
                descriptor.setTableName(tableName);
                for (IndexDefinition index : descriptor.getTables().get(0).getIndexes()) {
                    index.setTargetTable(tableName);
                }
                Vector<DatabaseMapping> mappings = descriptor.getMappings();
                camelCaseToUnderscore(mappings);
            } else if (descriptor.isAggregateDescriptor() || descriptor.isChildDescriptor()) {
                camelCaseToUnderscore(descriptor.getMappings());
            }
        }
    }

    private void camelCaseToUnderscore(Vector<DatabaseMapping> mappings) {
        for (DatabaseMapping mapping : mappings) {
            DatabaseField field = mapping.getField();
            if (mapping.isDirectToFieldMapping() && !mapping.isPrimaryKeyMapping()) {
                String attributeName = mapping.getAttributeName();
                String underScoredFieldName = camelCaseToUnderscore(attributeName);
                field.setName(underScoredFieldName);
            }
        }
    }

    private String camelCaseToUnderscore(final String name) {
        StringBuffer buf = new StringBuffer(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(Locale.ENGLISH);
    }
}

I think you have missed adding following line in your persistence.xml to say EclipseLink to use your own SessionCustomizer

<property name="eclipselink.session.customizer" value="your.company.package.name.JpaNameMappingCustomizer"/>

Refer

http://www.eclipse.org/eclipselink/documentation/2.5/dbws/creating_dbws_services002.htm

http://eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_session_customizer.htm#CHDFBIEI

In case you want to distinguish between non-annotated elements and annotated elements using @Column annotations, then I found a very beautiful example doing this:

public class CamelCaseSessionCustomizer implements SessionCustomizer {

@Override
public void customize(Session session) throws SQLException {
    for (ClassDescriptor descriptor : session.getDescriptors().values()) {
        // Only change the table name for non-embedable entities with no
        // @Table already
        if (!descriptor.getTables().isEmpty() && descriptor.getAlias().equalsIgnoreCase(descriptor.getTableName())) {
            String tableName = addUnderscores(descriptor.getTableName());
            descriptor.setTableName(tableName);
            for (IndexDefinition index : descriptor.getTables().get(0).getIndexes()) {
                index.setTargetTable(tableName);
            }
        }
        for (DatabaseMapping mapping : descriptor.getMappings()) {
            // Only change the column name for non-embedable entities with
            // no @Column already

            if (mapping instanceof AggregateObjectMapping) {
                for (Association association : ((AggregateObjectMapping) mapping).getAggregateToSourceFieldAssociations()) {
                    DatabaseField field = (DatabaseField) association.getValue();
                    field.setName(addUnderscores(field.getName()));

                    for (DatabaseMapping attrMapping : session.getDescriptor(((AggregateObjectMapping) mapping).getReferenceClass()).getMappings()) {
                        if (attrMapping.getAttributeName().equalsIgnoreCase((String) association.getKey())) {
                            ((AggregateObjectMapping) mapping).addFieldTranslation(field, addUnderscores(attrMapping.getAttributeName()));
                            ((AggregateObjectMapping) mapping).getAggregateToSourceFields().remove(association.getKey());
                            break;
                        }
                    }
                }
            } else if (mapping instanceof ObjectReferenceMapping) {
                for (DatabaseField foreignKey : ((ObjectReferenceMapping) mapping).getForeignKeyFields()) {
                    foreignKey.setName(addUnderscores(foreignKey.getName()));
                }
            } else if (mapping instanceof DirectMapMapping) {
                for (DatabaseField referenceKey : ((DirectMapMapping) mapping).getReferenceKeyFields()) {
                    referenceKey.setName(addUnderscores(referenceKey.getName()));
                }
                for (DatabaseField sourceKey : ((DirectMapMapping) mapping).getSourceKeyFields()) {
                    sourceKey.setName(addUnderscores(sourceKey.getName()));
                }
            } else {
                DatabaseField field = mapping.getField();
                if (field != null && !mapping.getAttributeName().isEmpty() && field.getName().equalsIgnoreCase(mapping.getAttributeName())) {
                    field.setName(addUnderscores(mapping.getAttributeName()));
                }
            }
        }
    }
}

private static String addUnderscores(String name) {
    if (name.equalsIgnoreCase("begintime")) {
        System.err.println();
    }
    StringBuffer buf = new StringBuffer(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();
}

}

From https://gist.github.com/ganeshs/c0deb77ffae33dee4555

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!