gpt4 book ai didi

java - 使用 EclipseLink 自定义 JPA 字段名称映射

转载 作者:搜寻专家 更新时间:2023-10-31 08:23:00 24 4
gpt4 key购买 nike

由于历史原因,我需要在当前使用 EclipseLink 的项目中将驼峰命名法映射为下划线分隔的名称。我知道我们可以在 JPA 中单独自定义名称映射,但我们有一长串驼峰命名法名称需要更改,因此我们希望尽可能避免这种样板代码。

我想达到的效果如下。假设我们有一个实体类如下:

@Entity
public class FooBar {
@Id @GeneratedValue
private Long id;

@Temporal( TemporalType.TIMESTAMP )
private Date dateCreated;
}

我希望此类映射到名称为“foo_bar”、列为“id”和“date_created”的表。请注意,数据库中的所有名称均为小写。

我四处搜索,找到了更改表名的解决方案。但是,我不知道如何更改实体类中的字段名称。

下面是我的名称映射定制器,其中方法 updateFieldNameMappings() 没有将 fieldName 映射到 field_name,这正是我想要的实现。问题归结为如何获取类定义中的字段名称。那么,如何在 EclipseLink 中执行此操作?

public class JpaNameMappingCustomizer implements SessionCustomizer {

@Override
public void customize( Session session ) throws Exception {
Map<Class, ClassDescriptor> descs = session.getDescriptors();
Collection<ClassDescriptor> descriptors = descs.values();

// This code assumes single table per descriptor!
for (ClassDescriptor desc : descriptors) {
updateTableNameMapping( desc );
updateFieldNameMapping( desc );
}
}

private void updateTableNameMapping ( ClassDescriptor desc ) {
Class clazz = desc.getJavaClass();
String tableName = camelCaseToUnderscore( clazz.getSimpleName() );
desc.setTableName( tableName );
}

private void updateFieldNameMapping ( ClassDescriptor desc ) {
// build name maps
Field[] fields = desc.getJavaClass().getDeclaredFields();
String tableName = desc.getTableName();
Map<String,String> nameMap = new HashMap<>();
String prefix = tableName + ".";
for( Field field : fields ) {
String name = field.getName();
String key = prefix + name.toUpperCase();
String value = prefix + camelCaseToUnderscore( name );
nameMap.put( key, value );
}

for (DatabaseMapping mapping : desc.getMappings()) {
if (mapping.isDirectToFieldMapping()) {
DirectToFieldMapping directMapping = (DirectToFieldMapping) mapping;
String oldFieldName = directMapping.getFieldName(); // format: table_name.FIELD
directMapping.setFieldName( nameMap.get( oldFieldName ) );
}
}
}

private String camelCaseToUnderscore( String camelCase ) {
return camelCase.trim().replaceAll("(?<!^)[A-Z](?!$)", "_$0").toLowerCase();
}
}

编辑 2013 年 11 月 10 日我做了一些黑客攻击并更改了定制器。 updateFieldNameMapping() 仍然无法解决问题。在我看来,方法中的这条语句 directMapping.setFieldName( nameMap.get( oldFieldName ) ) 实际上并没有改变字段名称映射,这让我很困惑。

编辑 2013 年 11 月 11 日我忘了说清楚我在 persistence.xml 中启用了 eclipselink.session.customizer。也就是说,我在 persistence.xml 中有如下一行:

<property name="eclipselink.session.customizer" value="pkg.JpaNameMappingCustomizer"/>

最佳答案

代替

directMapping.setFieldName(nameMap.get(oldFieldName ));

尝试:

directMapping.getField().resetQualifiedName(nameMap.get(oldFieldName));

这对我在 EclipseLink 2.5.0 下有用

关于java - 使用 EclipseLink 自定义 JPA 字段名称映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19896352/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com