Spring Data Rest PUT v.s PATCH LinkableResources - spring

I'm using Spring Data REST to expose my Entity's and their relationships. I have a OneToOne relationship between two Entity's and I'm trying to update/change the relationship with PUT and PATCH.
I noticed that Spring Data REST will only allow you to update linked resources - JPA mapped Entity's (OneToMany, ManyToOne, etc) which are also AggregateRoots (has a Repository) - via a PATCH and are ignored with a PUT.
This can be seen in the LinkedAssociationSkippingAssociationHandler class:
if (associationLinks.isLinkableAssociation(association)) {
return;
}
Why is this? What is the reasoning behind this?
Is it because the design wants us to treat the associations as resources themselves as seen in this part of the documentation? I can alter the relationship via a PUT with Content-Type text/uri-list but it feels unnatural and require an additional HTTP request.

From the Spring data REST 2.5.9.RELEASE the associations are not update on PUT request and only update using PATCH.
Changes in version 2.5.9.RELEASE (2017-04-19)
DATAREST-1030 - PATCH requests do not handle links to associations properly.
Other links about this:
DATAREST-1061: PUT-request with application/json media type payload cannot update association #OneToOne by URI
Domain Driven Design and Spring

Related

(Spring) How to force jpa to update with If-Match "*"?

I have an (put) endpoint in some micro service lets call it A which can call from outside of the domain and from another micro service inside the same domain.
I implemented if-match header with #Version annotation and working just fine but i need additional feature such as; they want to call this endpoint from another micro service at the same domain with "*" and i have to tell JPA to accept request without optimistic-locking.
How could i force JPA to update if the request come from same domain with "*"?
Ok i just fixed this. We were using JPA totaly wrong when updating entity. When update some entity you should just get this entity from repo and set its fields. For example;
FooData comes service layer from controller and FooEntity comes from repo. You should use FooData to just check fields of FooEntity and set null to (#Version) tagged row_version. This means jpa can automaticaly increase number and worked well to me.
Wrong Behaviour: Convert FooData into BarEntity type-> Set new values to BarEntity and repository save the new entity.
If i'm still doing wrong please update me, I'll be appreciated.

Spring MVC: Customizing view response (Json/XML) based on header or parameter

I have a Spring MVC application which returns Json and Xml based on what is requested per client call. I am using Jackson and Xstream to let Spring do the de-serialization of my java object into json or xml output.
My java object contains a bunch of attributes, at least 30. I would like to know if there is a way I can let Spring control which fields of my java object will be present in the json or xml based on a header or parameter attribute. So the client application will be able to identify itself and the backend will return only the fields necessary or "visible" for that specific client app. Of course I could go to the nasty approach of hard coding, but I would not like to do that as the number of client applications can increase or decrease and having a deployment anytime it happens with code changes is out of context.
Is there a way to instruct spring/jackson/xstream to control the output based on some providaded value?
I did a quick implementation and my current solution works like this: I have an xml with a list of client IDs (I use these ids to identify my client app) and for each ID I have a list of attributes that the client app needs from the java object. I created a interceptor and between the controller and the view, my interceptor gets the header information with the client ID, get the list of attributes and using the BeanWrapper (http://docs.spring.io/spring/docs/2.0.x/reference/validation.html) to create a new object with only the attributes required by the client with data, all the others remain null (I instruct Jackson and Xtream) to ignore null attributes. This approach works fine but I was wondering if there is another/better way to do this.
Thank you
TL

ServiceStack Receiving posts without entity

I've a scenario where I get changing post content. So I can't map it to an entity.
I need is to get the json body of the post.
I would like to create an entity with a Property "JSON" so if the url for this entity is called the body is filled.
Is there a way to do this ? or any other way fo have a generic endpoint for posts?
In WebAPI I created a parameterless method on a controller and analysed the body on my own.
See this section on Reading in and De-Serializing ad-hoc custom requests in ServiceStack's wiki.
E.g. you can use a custom request binder or get your Request DTO to implement IRequiresRequestStream to tell ServiceStack to skip the deserialization of the request DTO and directly retrieve the stream without populating the request DTO.

Spring annotation based configuration change

I have a spring MVC (3.1) web app using Hibernate that is all working correctly - today, I have tried to move the configuration completely over to annotation based config (only using xml for the security stuff that isnt yet supported by Spring in code config).
After some tuning I got the app starting with no errors and the home page loads correctly - however I am seeing some different behaviour with the Hibernate sessions - namely, I am getting the following error when loading a page that actually touches Hibernate entities:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.tmm.web.domain.Profile.connections, no session or session was closed
This is happening in the following scenario:
a request hits my #Controller and it loads the user Profile object
In the same method call (so we are not talking detached entities etc here) it tries to call profile.getConnections()
Profile.connections do not actually explicitly state a fetchtype, so should default to eager load (is my understanding?), but either way, the getConnections() call is directly after the loading of the profile - so would have thought even if it was being loaded lazily, it could easily just go back to the DB and load connections on demand.
//#Controller Code
Account viewedUser = accountService.loadAccountByUserName(userName);
model.put("viewedUserConnections", viewedUser.getUserProfile().getConnections());
//Profile Entity
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List connections = new ArrayList();
Now, I know about lazy loading etc, so it's not a question about that - like i mentioned all the Hibernate stuff was working correctly - so really my question is, what Spring configuration might affect this behaviour?
I can post my before and after xml vs annotation config, but am hoping that someone can point me in the direction of some config that I might have missed in switching.
Your assumptions are mainly wrong:
In the same method call (so we are not talking detached entities etc here)
The method is a method of the controller. In typical Spring applications, controllers are not transactional, but services are. So, unless you configured an "open session in view" filter or interceptor, the session is closed when the transactional service method returns, and the controller thus always uses detached entities
Profile.connections do not actually explicitly state a fetchtype, so should default to eager load
No. XxxToMany associations are lazy by default.
If the same code worked before the transition, my guess is that you had an open session in view filter or interceptor, and that you forgot it when migrating to annotations.

Auditing JPA entities in webapp : how to obtain logged-in user?

I have a simple auditing requirement for my JPA entities : keep the creation and last modification date and author. The author should be the currently logged-in user.
I would like to implement this using #PrePersist and #PreUpdate annotations on a base class, or a JPA interceptor (no additional framework).
However, in both cases, I need a way to access the currently logged in user, which is stored in the HttpSession.
How can I access this information from a method on my base entity class or from a JPA interceptor ?
Is there any best practice or any tested method on how to achieve that ?
I was thinking, maybe add a web interceptor that, for each request, puts the logged-in user object into a globally reachable ThreadLocal (e.g. inside a Spring singleton service), which would make it possible to look it up from anywhere...
Does that sound like a good idea ?
Any suggestion welcome !
Edit: found similar question here (found it only after posting my own through suggestions on the right) : Setting createdBy and updatedBy in JPA entities automatically
The conclusion seems to go in the direction of ThreadLocal... still, any feedback welcome !
If you do not use remote (EJB) calls then the idea to use ThreadLocal should work, as most containers use one thread for each request processed. You need to be careful when you put the user and when you delete it, as the container probably uses a thread pool and you don't want to leave the user object attached to a thread that might be used to process another request.

Resources