使用Spring Data JPA自动转换参数

14

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

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

    public String toString() {
       return id;
    }
}

所有的代码都使用了这个 ID 对象。然而在我们的实体中,我们将 ID 定义为一个 String

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个回答

21
你可以在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,则必须在persistence.xml中定义转换器,否则它不会被识别。 https://bugs.eclipse.org/bugs/show_bug.cgi?id=412454
  4. 在Spring上使用JPA时,包含转换器的包必须出现在EntityManagerFactoryBeanpackageToScan属性中。

1
谢谢,我已经花了两个小时来处理第二个数字。 - osundblad
一个类型为AttributeConverter<String,String>的转换器能起作用吗?它似乎没有被JPA检测到。 - Vladimir
2
同时在字段上使用@Convert@Enumerated是不允许的(我曾经犯过这个错误,结果转换器没有被考虑进去)。 - Julien Kronegg
@falsarella 怎样处理多数据源配置?当我使用多数据源配置时,无法从属性文件中获取属性值。 - Krish
如果您在转换器类中添加@Converter(autoApply = true),则可以省略@Convert...注释,并且转换器会自动应用于适合的所有位置。 - Datz
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接