spring-projects / spring-data-rest

Simplifies building hypermedia-driven REST web services on top of Spring Data repositories
https://spring.io/projects/spring-data-rest
Apache License 2.0
920 stars 563 forks source link

PATCH a collection throws exception [DATAREST-1041] #1407

Open spring-projects-issues opened 7 years ago

spring-projects-issues commented 7 years ago

Petar Tahchiev opened DATAREST-1041 and commented

Hey guys,

I have the following setup:

public class CategoryEntity {
    @ManyToMany
    private Set<ProductEntitiy> products;
}

now I wrote a test-case that issues a PATCH request to update the collection like this:

mockMvc.perform(patch("http://localhost:8080/categoryEntities/1").content(
                "{ \"products\" : [\"http://localhost:8080/productEntities/1\"]}").accept(
                MediaType.APPLICATION_JSON_UTF8_VALUE).contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)).andDo(print()).andExpect(
                status().isOk());

The results are the following: Spring Boot 1.5.2.SNAPSHOT= Ingalls SR1 = X Spring Boot 1.5.1.RELEASE = Ingalls REL = X Spring Boot 1.5.0.RELEASE = Ingalls REL = X Spring Boot 1.4.6-SNAPSHOT= Hopper SR8 = X Spring Boot 1.4.5 RELEASE = Hopper SR8 = X Spring Boot 1.4.4 RELEASE = Hopper SR7 = X Spring Boot 1.4.3 RELEASE = Hopper SR6 = X Spring Boot 1.4.2 RELEASE = Hopper SR5 = V Spring Boot 1.4.1 RELEASE = Hopper SR3 = V Spring Boot 1.4.0 RELEASE = Hopper SR2 = V Spring Boot 1.3.8 RELEASE = Gosling SR5 = V

And every single time the exception is the same:

Body = {"cause":{"cause":null,"message":"Can not construct instance of com.example.ProductEntity: no String-argument constructor/factory method to deserialize from String value ('http://localhost:8080/productEntities/1')\n at [Source: N/A; line: -1, column: -1]"},"message":"Could not read payload!; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.example.ProductEntity: no String-argument constructor/factory method to deserialize from String value ('http://localhost:8080/productEntities/1')\n at [Source: N/A; line: -1, column: -1]"}

I have jackson-hibernate5 on the classpath. Also I remember not so long ago the body of the request was like the following:

{ "products" : [1]}

(just the ids not the local url) so I tried that one too, but it failed with all of the versions of spring boot.

I'll provide a test project


8 votes, 13 watchers

spring-projects-issues commented 7 years ago

Petar Tahchiev commented

Here's the test-project:

https://github.com/ptahchiev/DATAREST-1041

spring-projects-issues commented 7 years ago

Alan Hay commented

I am also seeing this. The issue only occurs when you increase the number of items in the collection e.g. there are zero existing associations and you add one or you have one existing association and you send a PATCH request with > 1 item in the collection.

The pertinent code seems to be in DomainObjectReader lines 283-289:

if (!value.hasNext()) {

    Class<?> type = componentType == null ? Object.class : componentType.getType();
    collection.add(mapper.treeToValue(jsonNode, type));

    continue;
}
spring-projects-issues commented 7 years ago

Alan Hay commented

This issue was introduced in HOPPER-SR5. Workaround for now is to fall back to HOPPER-SR4.

This is a fairly major regression. Are you able to provide any update Oliver?

spring-projects-issues commented 7 years ago

Oliver Drotbohm commented

Would you mind giving the latest snapshots a try? We've fixed the broken handling for associations in PATCH requests for DATAREST-1030, which seems to be exactly the same case as described here

spring-projects-issues commented 7 years ago

Petar Tahchiev commented

I've upgraded to <spring-data-releasetrain.version>Ingalls-BUILD-SNAPSHOT</spring-data-releasetrain.version> but I get

[ERROR] Failed to execute goal on project nemesis-platform-core: Could not resolve dependencies for project com.nemesis.platform:nemesis-platform-core:jar:1.5.1.BUILD-SNAPSHOT: The following artifacts could not be resolved: org.springframework.data:spring-data-rest-core:jar:2.6.2.BUILD-SNAPSHOT, org.springframework.data:spring-data-rest-webmvc:jar:2.6.2.BUILD-SNAPSHOT: Failure to find org.springframework.data:spring-data-rest-core:jar:2.6.2.BUILD-SNAPSHOT in https://repository.nemesis.io/artifactory/libs-snapshot was cached in the local repository, resolution will not be reattempted until the update interval of nemesis-repository-snapshots has elapsed or updates are forced -> [Help 1]

Looking at the repository: http://repo.spring.io/libs-snapshot/org/springframework/data/spring-data-rest-webmvc/ I don't see the 2.6.2-BUILD-SNAPSHOT version

spring-projects-issues commented 7 years ago

Oliver Drotbohm commented

Thanks for pointing that out. Looks like our 2.6.x branch build was gone in Bamboo. Recreated, built. Artifacts should be available. https://build.spring.io/browse/SPRINGDATAREST-DATAWEB58-1

spring-projects-issues commented 7 years ago

Petar Tahchiev commented

Yep, I can confirm it works for me :)

spring-projects-issues commented 7 years ago

Petar Tahchiev commented

Works fine

spring-projects-issues commented 7 years ago

Petar Tahchiev commented

It was fine for about 2 weeks, but now it's broken again:

Can not construct instance of com.nemesis.platform.module.cms.core.entity.WidgetEntity: no String-argument constructor/factory method to deserialize from String value ('45601428301221872')
spring-projects-issues commented 7 years ago

Oliver Drotbohm commented

There haven't been any changes in the last two weeks. Stale snapshot?

spring-projects-issues commented 7 years ago

Petar Tahchiev commented

My demo project:

https://github.com/ptahchiev/DATAREST-1041

works fine with Ingalls-SR3 (April 19th) and fails with latest Ingalls-BUILD-SNAPSHOT

spring-projects-issues commented 7 years ago

Oliver Drotbohm commented

The has literally been not a single change since then

spring-projects-issues commented 7 years ago

Petar Tahchiev commented

Hi Oliver,

on April 12th you said the bamboo was gone and it has been fixed before but there was no new artifact and you pushed the artifact manually. Then on April 16th I checked with the latest SNAPSHOT and it was working fine. Then you released Ingalls-SR3 (which still works great) and it kept working fine for me until monday (I think) when it started failing again. I don't think it's a stale SNAPSHOT, because I build my demo project:

https://github.com/ptahchiev/DATAREST-1041

with mvn clean install -U to update the SNAPSHOTs

spring-projects-issues commented 7 years ago

Greg Turnquist commented

More information was gathered in https://github.com/spring-projects/spring-hateoas/issues/548. That issue has been closed deferring to this one

spring-projects-issues commented 7 years ago

Ali Mujuthaba commented

Has this issue been fixed?

spring-projects-issues commented 7 years ago

Alexander Simeonov commented

This issue is still present in 1.5.6. Downgrading to 1.4.2 does the trick, but this seems like a pretty major flaw that deserves attention and higher priority

spring-projects-issues commented 7 years ago

Oliver Drotbohm commented

Can anyone provide a project exposing the failure in a test case against the latest version (and snapshots)?

spring-projects-issues commented 6 years ago

Jan Zyka commented

Oliver Drotbohm: https://github.com/janzyka/spring-json-patch

Doesn't work with Ingalls-SR10 and neither with Ingalls-BUILD-SNAPSHOT

Any help much appreciated :)

spring-projects-issues commented 6 years ago

Vijay S Lakshman commented

I am facing a similar issue when using POST with Spring Boot 2, Spring Data REST 3.0.6 and a kotlin data class. See my example https://github.com/vijaysl/spring-data-rest