如何使用 spring 数据 jpa 处理 URI 类型的属性?

How to handle properties of type URI with spring data jpa?

假设有一个实体

@Entity
public class Article {
 // ...
  private String uri;

  public void setUri(URI uri) {
    this.uri = uri.toString();
  }

  public URI getUri() {
    return URI.create(uri.toString();
  }
}

和一个 spring 数据 jpa 存储库

public interface ArticleRepository extends CrudRepository<Article, Long> {
    Optional<Article> findByLink(URI link);
}

但使用 findByLink(URI) 方法失败并返回 InvalidDataAccessApiUsageException: Parameter value [http://foo.de/foo.html] did not match expected type [java.lang.String (n/a)]。这当然可以通过将参数类型更改为字符串来避免。但是然后每个URI在查询之前都必须转换为字符串。

如果必须使用 spring 数据 jpa 查询类型 URI 的属性,最好的处理方法是什么?

在您当前的配置中,您正在尝试将 URI 参数应用于字符串字段。由于显而易见的原因,这失败了

选项 1

您将字段更改为也采用 URI 并注册一个转换器以将 URI 转换为 DB 表示形式。

看起来像这样:

@Converter(autoApply = true)
public class UriPersistenceConverter implements AttributeConverter<URI, String> {

    @Override
    public String convertToDatabaseColumn(URI entityValue) {
        return (entityValue == null) ? null : entityValue.toString();
    }

    @Override
    public URI convertToEntityAttribute(String databaseValue) {
        return (StringUtils.hasLength(databaseValue) ? URI.create(databaseValue.trim()) : null);
    }
}

使用此转换器,您也可以将字段更改为 URI:

@Entity
public class Article {
 // ...
  private URI uri;

  public void setUri(URI uri) {
    this.uri = uri;
  }

  public URI getUri() {
    return this.uri;
  }
}

选项 2

我尝试了选项 1 并且可以确认它正在工作 - 但选项 2 是理论上的 - 我认为你正在使用 JPA 字段访问 - 所以 JPA 使用这些字段访问你的实体 - 我想如果你改变对 PROPERTY JPA 应该使用您的 getter 和 setter - 它们具有正确的类型,这样您的代码就可以工作了。

访问类型是使用映射注释的位置推断的。如果您注释字段,您将获得字段访问权限 - 如果您注释您的 getter,您将获得 属性 访问权限。还有一个实体级注解来设置访问级别javax.persistence.Access

@Access(PROPERTY)

尝试使用上面的注释来注释您的实体并试一试。