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();
}
}
上述代碼通過將駱駝大小寫字段名稱轉換爲db中的下劃線,在Openjpa 1.2.2中正確生成DDL。然而像em.persist()這樣的持久化操作會產生錯誤的SQL並失敗。OpenJPA - 擴展PersistenceMappingDefaults以將Camel-Case轉換爲下劃線
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_NUMBER5, TOTAL_AMOUNT5, TOTAL_COUNT5, MY_FILE_ID5) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)} [code=-28, state=S0022]
請注意,openjpa爲每列添加「5」。不知道這是從哪裏來的。的DDL FOO_FILE產生的是:
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))
只是爲了要仔細檢查我的邏輯是錯誤的,我換成correctName()的超類的方法(使用匈牙利表示法)。
protected void correctName(Table table, Column col) {
String name = col.getName();
name = removeHungarianNotation(name);
col.setName(dict.getValidColumnName(name, table));
}
也失敗了。
是否有人成功擴展了PersistenceMappingDefaults以更改列/表名稱?在這方面,與Hibernate相比,openjpa似乎太複雜了。