OpenJPA - 扩展PersistenceMappingDefaults以将Camel-Case转换为下划线

时间:2011-05-13 19:50:18

标签: jpa openjpa

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并失败。

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”。不知道这是从哪里来的。生成的FOO_FILE的DDL是:

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似乎过于复杂。

2 个答案:

答案 0 :(得分:0)

我已经测试了上面的代码,它适用于OpenJPA 2.2.0。

成功将驼峰式字段名称映射到db。

中的下划线

因此,字段private String taxRate;引用数据库列TAX_RATE,而无需使用@Column(name = 'TAX_RATE')进行注释

请记住,persistence.xml需要在<persistence-unit>

中定义这样的属性
    <properties>
        <property name="openjpa.jdbc.MappingDefaults"
            value="com.myproject.ImprovedMappingDefaults"/>
    </properties>

如果OpenJPA团队可以选择将其作为一个选项,例如 removeHungarianNotation ......

答案 1 :(得分:-1)

它适用于当前版本的OpenJPA。请参阅example here