OpenJPA - Extending PersistenceMappingDefaults to convert Camel-Case to Underscores
public class ImprovedMappingDefaults extends PersistenceMappingDefaults {
@Override
protected void correctName(Table table, Column col) {
String name = col.getName();
name = addUnderscores(name);
col.setName(dict.getValidColumnName(name, table));
}
// taken from Hibernate's ImprovedNamingStrategy
private static String addUnderscores(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();
}
}
The above code generates DDL correctly in Openjpa 1.2.2 by converting camel case field names to underscores in the db. However persistence operations like em.persist() generate erroneous SQL and fails.
org.apache.openjpa.lib.jdbc.ReportingSQLException: Column not found: VERSION5 in statement [INSERT INTO FOO_FILE (file_id, VERSION5, DATETIME05, FILE_NAME5, INPUT_SYSTEM5, IS_END_OF_DAY5, SEQUENCE_NUMBER5, TOTAL_AMOUNT5, TOTAL_COUNT5, MY_FILE_ID5) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)] {INSERT INTO FOO_FILE (file_id, VERSION5, DATETIME05, FILE_NAME5, INPUT_SYSTEM5, IS_END_OF_DAY5, SEQUENCE_NUMBER开发者_JS百科5, TOTAL_AMOUNT5, TOTAL_COUNT5, MY_FILE_ID5) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)} [code=-28, state=S0022]
Note that openjpa is appending "5" to each column. Not sure where this is coming from. The DDL for FOO_FILE generated is:
CREATE TABLE FOO_FILE (file_id BIGINT NOT NULL, VERSION INTEGER, DATETIME0 TIME, FILE_NAME VARCHAR(100), INPUT_SYSTEM VARCHAR(3), IS_END_OF_DAY BIT, SEQUENCE_NUMBER BIGINT, TOTAL_AMOUNT NUMERIC, TOTAL_COUNT INTEGER, MY_FILE_ID VARCHAR(255), PRIMARY KEY (file_id))
Just to double check if my logic was wrong, I replaced correctName() with the super class method (that uses Hungarian notation).
protected void correctName(Table table, Column col) {
String name = col.getName();
name = removeHungarianNotation(name);
col.setName(dict.getValidColumnName(name, table));
}
That fails too.
Has anyone successfully extended PersistenceMappingDefaults to change column/table names? It seems openjpa is too complicated compared to Hibernate in this regard.
I have tested your code above and it works for OpenJPA 2.2.0.
Successfully mapped camel-case field names to underscores in db.
So field private String taxRate;
refers to db column TAX_RATE
without having to annotate with @Column(name = 'TAX_RATE')
Remember that the persistence.xml needs a property like this to be defined in the <persistence-unit>
:
<properties>
<property name="openjpa.jdbc.MappingDefaults"
value="com.myproject.ImprovedMappingDefaults"/>
</properties>
It would be great if the OpenJPA team could take this in as an option, like removeHungarianNotation...
It works in current versions of OpenJPA. See example here.
精彩评论