在 Odata2 中可以重新定义元模型。以下页面描述了该过程:https://olingo.apache.org/doc/odata2/tutorials/jparedefinemetadata.html
我还没有找到使用 OData v4/Olingo/JPA 进行此类转换的方法。我正在使用 SAP 实现 olingo-jpa-processor-v4,该实现位于 https://github.com/SAP/olingo-jpa-processor-v4
我正在寻找的是更改某些类或属性的外部名称。
我尝试使用 JPAEdmNameBuilder 类,但该类的方法没有足够的信息来根据属性来自的实体来更改属性。这些方法仅接收属性的名称(而不是实体的名称),因此无法有选择地重命名出现在两个实体中的属性。
关于如何进行转换有什么建议吗?
非常感谢
注意:有一个相关问题:Olingo (OData 4): how set conversion of EntitySet (Entity) name? 但它相当古老且非常具体。我希望在这段时间内能够实现类似于 Odata2 中存在的功能。
这是一个相当老的线程,但我遇到了同样的问题,并找到了解决方案,因此将其发布在这里。
因此,在创建
JPAODataSessionContextAccess
时,您可以调用setEdmNameBuilder
函数来设置EdmBuilder。
如果JPAODataServiceContext
的第165行
中没有传递任何内容,则会创建并设置
JPADefaultEdmNameBuilder
的新实例。当前代码中的
JPADefaultEdmNameBuilder
被标记为 Final,因此您不能对其进行子类化,但您可以构建定义一个实现
JPAEdmNameBuilder
的类,该类具有您的自定义逻辑并在
JPAODataSessionContextAccess
中设置它
作为参考,设置自定义类的代码将类似于
@Bean
public JPAODataSessionContextAccess sessionContext(@Autowired final EntityManagerFactory emf) throws ODataException {
return JPAODataServiceContext.with()
.setPUnit(punit)
.setEntityManagerFactory(emf)
.setTypePackage(rootPackages)
.setRequestMappingPath("true/v1")
.setEdmNameBuilder(new CustomJPADefaultEdmNameBuilder("MyNameSpace"))
.build();
}
并且CustomJPADefaultEdmNameBuilder
的实现可以像下面这样
public class CustomJPADefaultEdmNameBuilder implements JPAEdmNameBuilder {
private final String namespace;
public static String firstToUpper(String jpaAttributeName) {
return Character.toUpperCase(jpaAttributeName.charAt(0)) + jpaAttributeName.substring(1);
}
public CustomJPADefaultEdmNameBuilder(@Nonnull String namespace) {
this.namespace = (String) Objects.requireNonNull(namespace);
}
public final String buildComplexTypeName(EmbeddableType<?> jpaEmbeddedType) {
return jpaEmbeddedType.getJavaType().getSimpleName();
}
public String buildContainerName() {
StringBuilder containerName = new StringBuilder();
String[] elements = this.namespace.split("\\.");
String[] var3 = elements;
int var4 = elements.length;
for(int var5 = 0; var5 < var4; ++var5) {
String element = var3[var5];
containerName.append(firstToUpper(element));
}
containerName.append("Container");
return containerName.toString();
}
public final String buildEntitySetName(String entityTypeName) {
return entityTypeName.charAt(entityTypeName.length() - 1) == 'y' && entityTypeName.charAt(entityTypeName.length() - 2) != 'a' && entityTypeName.charAt(entityTypeName.length() - 2) != 'e' && entityTypeName.charAt(entityTypeName.length() - 2) != 'i' && entityTypeName.charAt(entityTypeName.length() - 2) != 'o' && entityTypeName.charAt(entityTypeName.length() - 2) != 'u' ? entityTypeName.substring(0, entityTypeName.length() - 1) + "ie" + "s" : entityTypeName + "s";
}
public String buildEntityTypeName(EntityType<?> jpaEntityType) {
return jpaEntityType.getName();
}
public final String getNamespace() {
return this.namespace;
}
public final String buildNaviPropertyName(Attribute<?, ?> jpaAttribute) {
return this.buildPropertyName(jpaAttribute.getName());
}
public final String buildPropertyName(String jpaAttributeName) {
return firstToUpper(jpaAttributeName);
}
public final String buildOperationName(String internalOperationName) {
return firstToUpper(internalOperationName);
}
public final String buildEnumerationTypeName(Class<? extends Enum<?>> javaEnum) {
return javaEnum.getSimpleName();
}
}