使用ConversionFailedException在PUT调用上自定义实体查找失败

问题描述 投票:0回答:1

我有一个与this question非常相似的问题,但并不完全相同。我想使用基于字符串的外部id,所以在EntityLookup中设置自定义the documentation配置。

这适用于GETPOSTDELETE,但PUT失败了ConversionFailedException

我可以使用以下最小配置重现错误,以使用username作为要查找的字段:

user.Java

@Entity
public class User {
    @Id
    private Long id;
    private String username;
    private String fullName;
}

user repo.Java

@RepositoryRestResource(exported = true)
public interface UserRepo extends PagingAndSortingRepository<User, Long> {
    Optional<User> findByUsername(String username);
}

spring data rest customization.Java

public class SpringDataRestCustomization implements RepositoryRestConfigurer {
    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.withEntityLookup()
        .forRepository(UserRepo.class, User::getUsername, UserRepo::findByUsername);
    }
}

我可以然后POST新记录并通过GET /users/username获取它们,但PUT到现有资源会出现以下错误:

o.s.d.r.w.RepositoryRestExceptionHandler : Failed to convert from type [java.lang.String] to type [java.lang.Long] for value 'username'; nested exception is java.lang.NumberFormatException: For input string: "username"

org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Long] for value 'username'; nested exception is java.lang.NumberFormatException: For input string: "username"
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:46) ~[spring-core-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191) ~[spring-core-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:174) ~[spring-core-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    at org.springframework.data.mapping.model.ConvertingPropertyAccessor.convertIfNecessary(ConvertingPropertyAccessor.java:123) ~[spring-data-commons-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.data.mapping.model.ConvertingPropertyAccessor.setProperty(ConvertingPropertyAccessor.java:61) ~[spring-data-commons-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.data.rest.webmvc.config.PersistentEntityResourceHandlerMethodArgumentResolver.lambda$resolveArgument$3(PersistentEntityResourceHandlerMethodArgumentResolver.java:149) ~[spring-data-rest-webmvc-3.1.4.RELEASE.jar:3.1.4.RELEASE]
    at java.base/java.util.Optional.ifPresent(Optional.java:183) ~[na:na]
    at org.springframework.data.rest.webmvc.config.PersistentEntityResourceHandlerMethodArgumentResolver.resolveArgument(PersistentEntityResourceHandlerMethodArgumentResolver.java:146) ~[spring-data-rest-webmvc-3.1.4.RELEASE.jar:3.1.4.RELEASE]
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:126) ~[spring-web-5.1.4.RELEASE.jar:5.1.4.RELEASE]
spring spring-data spring-data-rest
1个回答
0
投票

那绝对是一个错误。

这是因为PUT repository/{id}端点也可用于创建具有给定id的新实体。因此,在PUT请求期间,它会尝试将URL中的id放入对象的id属性中。但是 - 因为你有一个独特的EntityLookup - URL片段不是实体的id属性......

似乎作者只是忘了处理这个案子。当我看到源代码时,我看不到任何简单的解决方法。

我认为PATCH请求仍然有效,所以如果你可以避免使用PUT请求,那么这可能是一个解决方案。

我个人不喜欢这整个EntityLookup功能。 (事实证明:听起来不错,不起作用:))我认为URL的id片段应该是实体的实际id。也许它并没有违反REST原则,但我仍觉得不合适。

如果您想通过用户名获取用户,则可以随时使用users / search / findByUsername端点,之后如果您想稍后通过PUT请求修改对象,您将在响应中拥有_self链接。

© www.soinside.com 2019 - 2024. All rights reserved.