首页 > 解决方案 > 在 @where 注释上应用自定义物理命名策略

问题描述

我通过扩展 PhysicalNamingStrategyStandardImpl 来设置 CustomPhysicalNamingStrategy 以prefix__在与 DB 映射之前附加“”表和列名。如果是普通的表名和列名(用 注释的列名@Column, @ColumnName),它对我有用,但对于@Where.

@Where(clause = "item__c is null")

为此:item__c不会更改为prefix__item__c.

休眠日志就像.....where ( serviceite0_.item__c is null).....

请就此提出建议。

我已经用 spring-boot 2.0.8.RELEASE 尝试过这个用例。

应用程序.yml:

spring:
  jpa:
    hibernate:
     naming:
       physical-strategy: com.echo.dataprovider.config.CustomPhysicalNamingStrategy
       implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl

CustomPhysicalNamingStrategy.java

 public class CustomPhysicalNamingStrategy extends PhysicalNamingStrategyStandardImpl {

    private static final long serialVersionUID = -6136290474018632737L;

    @Override
    public Identifier toPhysicalColumnName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return addPrefix(super.toPhysicalColumnName(identifier, jdbcEnv));
    }

    @Override
    public Identifier toPhysicalTableName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return addPrefix(super.toPhysicalTableName(identifier, jdbcEnv));
    }

    private Identifier addPrefix(final Identifier identifier) {
        return (identifier == null
                || !identifier.getText().matches("(.*)" + "__A" + "(.*)"))
                        ? identifier
                        : Identifier.toIdentifier(String.join("__B__",
                                Arrays.stream(identifier.getText().split("__B__"))
                                        .map(m -> "prefix__" + m).toArray(String[]::new)));
    }
    }

模型.java

@Entity
@Table(name = "service__c", schema = "abc")
public class Service {

    @Id
    @Column(name = "id")
    private String id;

    @OneToMany(mappedBy = "service")
    **@Where(clause = "item__c is null")**
    private List<Item> itemList;
...

预期的:

@Where(clause = "item__c is null")

为此:item__c应更改为prefix__item__c.

标签: javaspringhibernatespring-bootjpa

解决方案


@Where文档

该子句是用 SQL 编写的

PhysicalNamingStrategy只能与 JPA 名称一起使用。Hibenrate 文档的这一部分没有明确说明,但从这些陈述中可以清楚地看出:

JPA 兼容性

JPA 定义了关于隐式逻辑名称确定的固有规则。如果 JPA 提供程序可移植性是一个主要问题,或者如果您真的只是喜欢 JPA 定义的隐式命名规则,请务必坚持使用 ImplicitNamingStrategyJpaCompliantImpl(默认)

此外,JPA 没有定义逻辑名称和物理名称之间的分隔。按照 JPA 规范,逻辑名称是物理名称。如果 JPA 提供者的可移植性很重要,应用程序不应该指定 PhysicalNamingStrategy。

不幸的是,您需要在@Where子句中使用全名。


推荐阅读