Customize JPA field name mapping using EclipseLink

后端 未结 4 1821
名媛妹妹
名媛妹妹 2021-01-12 16:01

I need to map camel-case names to underscore-separated names in my current project, which uses EclipseLink, due to historical reasons. I know we can customize name mapping i

4条回答
  •  一生所求
    2021-01-12 16:24

    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 mappings = descriptor.getMappings();
                    camelCaseToUnderscore(mappings);
                } else if (descriptor.isAggregateDescriptor() || descriptor.isChildDescriptor()) {
                    camelCaseToUnderscore(descriptor.getMappings());
                }
            }
        }
    
        private void camelCaseToUnderscore(Vector 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);
        }
    }
    

提交回复
热议问题