Patch request on an Entity with @Version/ETag fails when using a projection [DATAREST-1213] #1573
Comments
Dario Seidl commented In the last project, we managed to work around this issue by avoiding patch with projections. Now I'm facing the problem again in a different project after upgrading to Spring Boot 2. This time we don't even have any Is there a way to disable the HttpHeadersPreparer or the ETag altogether? |
Oliver Drotbohm commented I'm not sure I want to go forward with this. As of now (and documented PATCH and PUT requests are not even supposed to support projections and even with this one fixed, I am pretty sure there are many other parts of the codebase that break trying to use them for those. You might get them to work in simple cases but e.g. open projections clearly won't work as the contain synthetic properties. I am even pretty sure that you'd never even get a properly projected instance created for a PUT request based on the current code, i.e. the assumption in your tests that the payload would consist of a projection instance is invalid in the first place. The To handle the situation better I'd like to find out what's causing the instance returned by |
Dario Seidl commented Thank you for the answer. I understand not wanting to support this if it is not supposed to work. However, it did work in previous versions, and seems to work with some adjustments. I'd be happy to look some more into it. I narrowed down where the proxy is created. You're right the In the end, in I don't know about all cases, but patch and put with open projections (with a Please take a the linked etagdemo project. It's a very simple project with a few tests to reproduce the issue. There is nothing special done to the repositories there, AFAIK. In this project I have only customized the |
Dario Seidl commented I have updated the pull request with web tests and moved the the code to unproxy the JDK proxy to the In Maybe you have another idea how this could be solved in a cleaner way? |
Oliver Drotbohm commented I think I now better understand the situation and you're basically right: I think it's fair to assume that for that particular overload this is totally fine and we should probably add an assertion for this to make sure we fail earlier. I think adding a Feel free to update the PR accordingly or ping me in case you want me to take over. Happy to take it from here. Thanks for the vey helpful ping pong already! |
Dario Seidl commented OK, great! I've updated the pull request with the getter and an assertion in |
Dario Seidl commented Hello, just checking in to ask if this is ready to be merged? Let me know if you need something else from me |
Josh Wand commented This is biting us on upgrading our project too. Oliver Drotbohm would appreciate reviewing/merging the PR! Thanks! |
Prashant Srivastava commented Hi Its failing for RepositoryEntityController.createAndReturn(RepositoryEntityController.java:486) if we give projection in POST call prepareHeaders code need to be change for this Error: -public HttpHeaders prepareHeaders(Optional<PersistentEntityResource> resource) {- -- -return resource//- -.map(it -> prepareHeaders(it.getPersistentEntity(), it.getContent()))//- -.orElseGet(() -> new HttpHeaders());- -}- public HttpHeaders prepareHeaders(Optional<PersistentEntityResource> resource) { return resource// .map(it -> prepareHeaders(it.getPersistentEntity(), it.getTargetEntity()))// .orElseGet(() -> new HttpHeaders()); } |
Adrian Fish commented Oliver Drotbohm This issue is hitting us on the Sakai project. We just updated to Spring 5 and data rest 3.3.4 and our patch updates to our entities are failing to return our projected JSON. Same error as above. Dario Seidl's PR looks sensible to me. If it can't just be merged, is there a workaround? |
Adrian Fish commented Mark Paluch Do you have any insight into this issue? The manifestation of this is that projected entities can't have the request body returned because of a mismatch between a proxied and an unproxied entity. It seems to me that I can either run a patched spring data rest (don't want to) or rewrite my client side components to just not expect a body returned, and disable body returning on the server. Another option would be to be able to just turn etag generation off, make it configurable, but I can't find any docs on whether that's possible. In other words, just duck that entity comparison. Dario Seidl's patch works, or worked, but maybe the team wants to dig a little deeper |
Adrian Fish commented Any update on this? Unless this gets fixed I'm going to have to rewrite a chunk of code, just because we upgraded to the latest data rest. I'm sure there are others in the same boat |
Dario Seidl commented It's been a while since I've dealt with this, but we are also still affected in one project by this bug. From what I remember: there is no way to generally disable ETags, at least not in a way that would workaround this issue. If an entity doesn't have a We had a relatively big project without The only way we found to make it work again was applying the workaround, that I have submitted as a patch here too. Otherwise we would have to rewrite all PATCHes and PUTs to be followed by a GET to get the updated version. So we would too be very happy if this could be merged or resolved in another way. For what it's worth, our project has been running with that patch for 2+ years without issues now |
Oliver Drotbohm commented Sorry for the unusually long delay. I think I can get this integrated into the services releases coming up next week |
Adrian Fish commented That's great news! Thanks |
Oliver Drotbohm commented That's in place now. Feel free to give the snapshots a spin. Release due on Wednesday |
Dario Seidl commented Great, thank you! I gave it a quick try with Spring Boot 2.3.5 and Data Rest 3.3.5 and it seems to be working fine. :) |
Dario Seidl opened DATAREST-1213 and commented
Hello!
I have a Spring Boot 2 project, with Spring Data Rest 3.0.5.
When I create an Entity with a
@Version
field to generate ETags, and I make a patch request on that entity with a projection, I get the following error from an assertion in ETag.getVersionInformation:I understand that a projection would not affect the patch, but when using return-body-on-update, it would make sense to use a projection to determine the result body of a patch.
I have created a sample project on Github. Simply run the tests to see the problem.
This looks very similar to bug report DATAREST-581, but this one has been marked as resolved a long time ago
Affects: 3.0.5 (Kay SR5)
Reference URL: https://github.com/darioseidl/etagdemo
Referenced from: pull request #355
Backported to: 3.3.5 (Neumann SR5), 3.2.11 (Moore SR11)
4 votes, 4 watchers
The text was updated successfully, but these errors were encountered: