Entity property and columnName mapping

Now, I’m using hibernate(5.6) through springbootjpa(2.7.4), and I have encountered a problem. In a case sensitive database (even column names), I annotated a property with @Column annotation and gave an uppercase column names, but in Hibernate, it was converted to lowercase.

I checked the source code and found that in the Ejb3Column class, the explicitly specified column names have been converted by PhysicalNamingStrategy; By default, SpringPhysicalNamingStrategy is used in springboot, which always converts column names to lowercase.

Ejb3Column.java

public void redefineColumnName(String columnName, String propertyName, boolean applyNamingStrategy) {
		...

		if ( applyNamingStrategy ) {
			if ( StringHelper.isEmpty( columnName ) ) {
// there is no @Column annotationed 
				...
				//Do nothing otherwise
			}
			else {
				final Identifier explicitName = database.toIdentifier( columnName );
				final Identifier physicalName =  physicalNamingStrategy.toPhysicalColumnName( explicitName, database.getJdbcEnvironment() ); // HERE!!!, the explicitColumnName has been converted
				mappingColumn.setName( physicalName.render( database.getDialect() ) );
			}
		}
		else {
			if ( StringHelper.isNotEmpty( columnName ) ) {
				mappingColumn.setName( normalizer.toDatabaseIdentifierText( columnName ) );
			}
		}
	}

SpringPhysicalNamingStrategy.java

public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironment) {
    return apply(name, jdbcEnvironment);
}

private Identifier apply(Identifier name, JdbcEnvironment jdbcEnvironment) {
    if (name == null) {
       return null;
    }
    StringBuilder builder = new StringBuilder(name.getText().replace('.', '_'));
    for (int i = 1; i < builder.length() - 1; i++) {
       if (isUnderscoreRequired(builder.charAt(i - 1), builder.charAt(i), builder.charAt(i + 1))) {
          builder.insert(i++, '_');
       }
    }
    return getIdentifier(builder.toString(), name.isQuoted(), jdbcEnvironment);
}

protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
    if (isCaseInsensitive(jdbcEnvironment)) {
       name = name.toLowerCase(Locale.ROOT); // HERE!!! lowercase
    }
    return new Identifier(name, quoted);
}


protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
    return true;
}

So, why not directly using the explicit-name without converting by naming-strategy for those columns which are annotated by @Column with name=”Col_NAME”?

Just comment the line.

// final Identifier physicalName =  physicalNamingStrategy.toPhysicalColumnName( explicitName, database.getJdbcEnvironment() );

Sorry, but Hibernate ORM 5.6 is not supported anymore, so even if there is a bug, it won’t be fixed unless you’re a Red Hat or IBM customer and open a support ticket. Please update to the latest stable version Hibernate ORM 7.2.