I'm developing a Dropwizard app and am facing a strange bug on a GET request after I have included mongojack.
I have a simple GET query with the ID as a path parameter. It worked before I included mongojack and added two annotations to my entity:
public class Bill {
#javax.persistence.Id #org.mongojack.ObjectId
private String id;
#javax.persistence.Id #org.mongojack.ObjectId
public String getId() { return id; }
//...
}
What puzzles me most is that the request is actually accepted. When I debug, I can step into the method. The entity is loaded from MongoDB into memory and looks fine. So I suspect that this might actually be serialization issue, but currently I'm stuck. Any ideas?
Update
Seems to be a known mongojack issue: https://github.com/devbliss/mongojack/issues/26. Later I want to use custom DTOs without ObjectIds for my GETs anyway, so this shouldn't be relevant anymore. What I still don't understand is why Dropwizard maps this to a 400 response...
What I still don't understand is why Dropwizard maps this to a 400 response
Dropwizard, via Jackson, generates JSON using all the getters (or #JsonProperty annotated fields/methods) as you know. If any exception occurs on getters (or setters on deserialization) dropwizard automatically returns 400 Bad Request.
I guess that makes sense since it expects simple POJO DTOs with dumb getters and setters.
Related
Let say I have the following POJO
public class Plan{
private Long id;
private String name;
//other fields,getters, builder..
}
Now let say there is some Plan which already exist in db.
Now I am trying to modify/update various fields of this particular Plan by using the restAPI(api/v1/Plan/123).
Now we use Jackson here,so I will get the updated Plan object.I will be validating this updated Plan object and if all good will persist in the db.
Till here there is no issue.
But we using an internal service to audit this,i.e what all details got modified in this particular Plan and done by whom at what time etc.
For ex:Plan name changed from (Plan1 to Plan2)
Internal service will accept argument as (oldPlan,newPlan).
Now how can I get the oldPlan from the newPlan object?[Since the file which I have now got the method as public Plan update(Plan newPlan),inside this method only we will be calling an internal service method which requires oldPlan]
Constraints:
1.I should not fire the query getting the id from the newPlan,since that will be duplicate query coz it was already queried when creating newPlan object using jackson.
2.I should not change the update method signature and in update method the plan object which we receive via argument is the object which got updated details in it.
What I have in my mind is:
a)Having the Plan object itself in the POJO ,so that when I get newPlan.getPlan() will return the oldInstance?
The above approach can be done but I am not sure abt this.Whats the best approach to achieve this?
I got the response body from the HttpServletResponse with ContentCachingResponseWrapper used.
Now, I introduced custom annotations for the entities fields in my app and I need response body returned without the fields that I have annotated.
I do not want to affect my application behavior.
For example:
#Entity
public class User implements Serializable{
....
#Column
private String firstname;
#MyCustomAnnotation
#Column
private String lastname;
...
The real response body for the client should look like:
{"firstname":"John", "lastname":"Smith"}
And response body that I need for my later work is:
{"firstname":"John", "lastname":"MyCustomAnnotation"}
or
{"firstname":"John"}
or similar.
I was wondering if it is possible to do such a thing? Can I get one version of the response(filtered) and send client real version of the response?
I would like to avoid changing of the application code (methods in the controllers, model etc.), if it's possible. I would like to do all my work in the class where I am dealing with the HttpServletResponse.
What you probably need are json views, or if you simply want to ignore a field in your response - then #JsonIgnore
This may be a simple task, but I couldn't find a way to do it. Basically, I need to disallow some parameters at the time of using #RequestBody annotation in my controller.
Here is my model:
#Data
public class MyModel {
private int id;
private String name;
}
What I want to do is at the time of response, I want both of the properties to be serialized to JSON, but at the time of create or update, I prefer not to receive id as part of #RequestBody deserialization.
Right now, if I pass id in the JSON body, Spring initializes a MyModel object with its id set to the passed value.
Reason? The ID cannot be generated until the model is created, so the app shouldn't allow the ID to be set. On update, the ID needs to be passed in the URL itself e.g. (PUT /mymodels/43). This helps following the REST principles appropriately.
So, is there any way to achieve this functionality?
Update 1:
Right now, I am stuck with using a request wrapper. I created a new class MyModelRequestWrapper with only name as its property, and have used it with the #RequestBody annotation.
How you do this depends on what version of Jackson you are using. It's basically possible by a combination of the annotations #JsonIgnore and #JsonProperty on relevant fields/getters/setters.
Have a look at the answers here: Only using #JsonIgnore during serialization, but not deserialization
Is it possible to delete entities using an entity's unique attribute?
In Spring Data 1.4.3.RELEASE, adding methods to find by unique attributes is very easy but, I haven't found a way to do it with delete.
In the following code, Spring automagically handles the findByAddress, is there something similar for delete?
Something like void deleteByAddress(String hwAddress);, I have added it to TerminalRepository but it doesn't work.
public Terminal {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
#Column(unique=true)
private String hwAddress;
...
}
public interface TerminalRepository extends
CrudRepository<Terminal, Long> {
Terminal findByAddress(String hwAddress);
}
Of course it is possible to find the entity by address and then use the delete(Terminal) method passing the found entity as parameter. But this wouldn't be good in terms of performance as it will be making one unnecessary call to the database database, i.e., one avoidable call to find the object and another one to delete it
I don't think there's anything built-in for that. You'd have to use the custom method support to roll your own:
http://docs.spring.io/spring-data/jpa/docs/1.4.3.RELEASE/reference/html/repositories.html#repositories.custom-implementations
I was facing the same issue. But, when I annotated method in repository interface with #Modifying , it started working. But, I don't know how it started working. Can anybody explain?
My team is coding an application that involves editing wikipedia-like pages.
It is similar to the problem we have with registration:
A straightforward implementation gives something like
public static void doRegistration(User user) {
//...
}
The user parameter is a JPA Entity. The User model looks something like this:
#Entity
public class User extends Model {
//some other irrelevant fields
#OneToMany(cascade = CascadeType.ALL)
public Collection<Query> queries;
#OneToMany(cascade = CascadeType.ALL)
public Collection<Activity> activities;
//...
I have read here and there that this fails. Now, in Play!, what is the best course of action we can take? There must be some way to put all that data that has to go to the server in one object, that easily can be saved into the database.
EDIT: The reason this fails is because of the validation fail. It somehow says "incorrect value" when validating collection objects. I was wondering if this can be avoided.
SOLUTION: Changing the Collection to List has resolved the issue. This is a bug that will be fixed in play 1.2 :)
Thanks beforehand
this works. To be more clear, you can define a controller method like the one you wrote:
public static void doRegistration(User user) {
//...
}
That's completely fine. Just map it to a POST route and use a #{form} to submit the object, like:
#{form id:'myId', action:#Application.doRegistration()}
#{field user.id}
[...]
#{/form}
This works. You may have problems if you don't add all the field of the entity in the form (if some fields are not editable, either use hidden inputs or a NoBinding annotation as described here).
EDIT: on the OneToMany subject, the relation will be managed by the "Many" side. That side has to keep the id of the related entity as a hidden field (with a value of object.user.id). This will solve all related issues.
It doesn't fail. If you have a running transaction, the whole thing will be persisted. Just note that transactions are usually running within services, not controllers, so you should pass it from the controller to the service.