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

gre*_*gor 3 java spring 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();
  }
}
Run Code Online (Sandbox Code Playgroud)

和一个spring数据jpa存储库

public interface ArticleRepository extends CrudRepository<Article, Long> {
    Optional<Article> findByLink(URI link);
}
Run Code Online (Sandbox Code Playgroud)

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

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

Mat*_*nkt 6

在当前配置中,您尝试将URI参数应用于字符串字段.这显然是因为失败

选项1

您也可以更改字段以获取URI并注册转换器以将URI转换为数据库表示形式.

这看起来像这样:

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

  public URI getUri() {
    return this.uri;
  }
}
Run Code Online (Sandbox Code Playgroud)

选项2

我尝试了选项1并且可以确认它正在运行 - 但是选项2是理论上的 - 我认为您正在使用JPA字段访问 - 因此JPA使用字段访问您的实体 - 我认为如果您更改对PROPERTYJPA 的访问权限应该使用您的getter和setter - 它们具有正确的类型,因此您的代码可以正常工作.

使用映射注释的位置推断访问类型.如果您对字段进行注释,则可以获得字段访问权限 - 如果您对获取者进行注释,则可以访问该属性.还有一个实体级注释来设置访问级别javax.persistence.Access

@Access(PROPERTY)
Run Code Online (Sandbox Code Playgroud)

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