使用弹簧数据 JPA 自动转换参数

2022-09-04 01:47:00

在我们的实体 Bean 中,我们使用自定义 ID 格式,其中包含校验和来验证 ID 是否确实有效。ID 看起来像 .为了确保所有代码仅使用正确的 ID,我们围绕 ID 字符串创建了一个代码包装器:ID827391738979

class ID {
    public ID(String id) {
       // parse and verify ID
    }

    public String toString() {
       return id;
    }
}

所有代码都只使用此对象。但是,在我们的实体中,我们将ID定义为:IDString

class SomeEntity {
    @Column
    private String itsID;
}

现在我们想使用Spring-Data-JPA来查询某个对象的id。所以我们这样做:

public SomeEntity findByItsID(ID itsId);

问题是,现在Spring Data JPA尝试将ID类型参数分配给查询,而查询当然需要.String

是否可以让Spring Data JPA在将参数插入查询之前将其转换为预期类型(例如,通过注册Spring转换器)?或者,我们是否必须让该方法采用如下所示的字符串:

public SomeEntity findByItsId(String itsId);

我宁愿避免这种情况,这样所有代码都可以使用该类,而不是求助于字符串。ID


答案 1

您可以在实体中使用JPA 2.1@Convert自定义类型,因此JPA为您进行转换(我也使用Spring Data JPA对其进行了测试,并且它的工作方式透明!),请参阅:

实体:

@Entity
class SomeEntity {

    @Column(name = "my_id_column_name")
    @Convert(converter = MyIDConverter.class)
    private ID itsID;
}

转炉:

public class MyIDConverter implements AttributeConverter<ID, String> {

    @Override
    public String convertToDatabaseColumn(ItStaticDataKey javaKey) {
        // your implementation here
    }

    @Override
    public ItStaticDataKey convertToEntityAttribute(final String databaseKey) {
        // your implementation here
    }

}

笔记:

  1. 确保您使用的是与 JPA-2.1 兼容的 Spring Data JPA 版本。(我确信Spring Data JPA 1.7.0(及更高版本)是(或至少应该)兼容的)。
  2. 不幸的是,如果该字段也应该用@Id注释,它将不起作用
  3. 如果你使用EclipseLink,你必须在持久性中定义转换器.xml,否则它不会拾取它。https://bugs.eclipse.org/bugs/show_bug.cgi?id=412454
  4. 使用 Spring 上的 JPA 时,包含转换器的包必须出现在 的属性中。packageToScanEntityManagerFactoryBean

答案 2

推荐