Spring MVC: Bind Input field to multiple properties - java

I am trying to get Spring MVC to bind the value from one input field to multiple properties.
My use-case is a forum, that contains a form to create a new topic. That dialog actually create a topic and a post, which both have the same title, so only one input field exists for the title. If I copy the value myself in the controller method, using the "#Validated" annotation in the signature won't work, since the validator is called before I can copy the value, and so the title would still be missing in one field. Of course I can call the validator myself after copying the value, but if at all possible I would prefer if Spring would bind that value itself, just to get a clean solution (and to learn if and how it is possible).
Best regards,
Christian

Related

Why does Spring-data-jdbc not save my Car object?

I'm playing around with spring-data-jdbc and discovered a problem, with I can't solve using Google.
No matter what I try to do, I just can't push a trivial object into the database (Bean1.java:25):
carRepository.save(new Car(2L, "BMW", "5"));
Both, without one and with a TransactionManager +#Transactional the database (apparently) does not commit the record.
The code is based on a Postgres database, but you might also simply use a H2 below and get the same result.
Here is the (minimalistic) source code:
https://github.com/bitmagier/spring-data-jdbc-sandbox/tree/stackoverflow-question
Can somebody tell me, why the car is not inserted into the database?
This is not related to transactions not working.
Instead, it's about Spring Data JDBC considering your instance an existing instance that needs updating (instead of inserting).
You can verify this is the problem by activating logging for org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate. You should see an update but no insert.
By default, Spring Data JDBC considers an entity as new when it has an id of an object type and a value of null or of a primitive type (e.g. int or long) and a value of 0.
If your entity has an attribute with #Version annotation that attribute will be used to determine if the instance is a new one.
You have the following options in order to make it work:
Set the id to null and configure your database schema so that it will automatically create a new value on insert. After the save your entity instance will contain the generated value from the database.
Note: Spring Data JDBC will set the id even if it is final in your entity.
Leave the id null and set it in a Before-Convert listener to the desired value.
Let your entity implement Persistable. This allows you to control when an entity is considered new. You'll probably need a listener as well so you can let the entity know it is not new any longer.
Beginning with version 1.1 of Spring Data JDBC you'll also be able to use a JdbcAggregateTemplate to do a direct insert, without inspecting the id, see https://jira.spring.io/browse/DATAJDBC-282. Of course, you can do that in a custom method of your repository, as is done in this example: https://github.com/spring-projects/spring-data-examples/pull/441

Spring Redis JSON serializer embeds referenced field

I have a class which has many simple attributes (type is int,String,...). It also has an attribute which is an instance of another class of mine. Now I want to send the object via a Redis pub/sub channel. To do this I serialize it with the GenericJackson2JsonRedisSerializer. As both classes have their own repository I don't want to embed the object every time but instead only send the ID. I thought that this should be possible by adding the org.springframework.data.annotation.Reference annotation to the field.
Unfortunately this didn't work, instead it just embeds the object. Is there anything I did wrong? What do I have to do to just get the object's ID in the serialized version?
Thank you for your help!
Alright after way too much research for such a basic thing I finally figured out how to do it.
Basically I needed to add the com.fasterxml.jackson.annotation.JsonIdentityInfo annotation to the class or field. As already stated in the question this produced the same result, first time completely included, afterwards only referenced.
No documentation mentioned how to always have the id, I had to look into the code: there's another annotation com.fasterxml.jackson.annotation.JsonIdentityReference which has a boolean property called alwaysAsId. If you set this one to true it always adds the id instead of the object.
To get the deserializing working one needs to specify a custom resolver for the ids. As I'm using Spring it has been quite easy to get access to my repository.
Did you use Spring Data Redis ? http://projects.spring.io/spring-data-redis/
Check http://docs.spring.io/spring-data/redis/docs/current/reference/html/#redis.repositories.references
If you are not using Spring Data Redis I think you should have to implement your own reference when serialize/deserialize your data.
You can implements your own Serializer with
YourObjectSerializer extends Jackson2JsonRedisSerializer

How to write a bean auto complete in wicket 1.4?

I want a bean auto complete.
I like the way the wicket DropDownChoice works.
We can add ChoiceRenderer to the DropDownChoice to display whatever we want.
And we can also set a bean object as the model object.
I want the auto complete to work exactly the same way.
I have tried it several times, but in vain.
I know there AbstactAutoCompleteRender and all, but I have always found that, the auto completes work well with Strings only.
So I have to convert my bean list to string list of some attribute of the bean and then do the auto complete logic, and then figure out the bean by doing some operations on the String (the model object).
It's working but, it's just too much of hustle for a thing, that can be easily done in DropDownChoice.
May be in latter version of wicket there is a bean auto complete, but is there any ways to achieve a simple bean auto complete in wicket 1.4.x?
wicket-extensions' Autocompleter works only with String as a model.
You can use https://github.com/wicketstuff/core/tree/core-1.4.x/jdk-1.5-parent/objectautocomplete-parent instead.

Specific configurations for different items using same table

So we have an ITEM, TV, LCD and PROJECTOR.
We have DAO and Service object for TV, LCD and PROJECTOR that also are ITEM objects. Meaning that those tables all extends the ITEM table.
You can access these items through an UI and an API service.
Right now, I am in the need to put specific UI configurations that are not related at all with the API. Lets say that I need in the UI a configuration for each item to display or not display an image of the item on it, lets call it showImageFlag. This value can be modified from the Item's UI, this is a checkbox.
I've been thinking about a few options here:
Add a column SHOW_IMAGE_FLAG to the ITEM table and it's DAO and service object. On the service object put a #JSonIgnore flag so it is ignored on the API side, but we can use it normally in the UI. ------- My concern with this approach is that in the future we might need more configuration for these items or maybe others than tv, lcd and projector. So this will always will push us to add a new column to the table. Another concern is that we might be migrating all form post ui to use the REST API, so we are going to have to do something about that JsonIgnored property.
A ITEM_CONFIG (id, item_id, configuration, value) table FKed to the ITEM.id with a key/value approach to save N configuration related to specific items. So on every web controller I will be passing a ItemConfig object with all configurations related to the requested ITEM. -------- My concern with this one, is how should I map this to the form (using spring mvc) and how should I persist when the configuration changes on the UI.
Please free to comment and suggest any new option for this.
Second point is more feasible.
Also,you can have another service layer which will be responsible for saving mapping part and below service layer there will be UI controller layer which will actually map the changes to its undergoing presentation i.e. UI layer.
I would think about adding Item(id)--ItemUI(item_id) as 1:1.
Then you can add all your UI specific about an item to the ItemUI attributes.
Also you could request UI configuration with a second call to another service.
From the two options I'll go for number one. The only problem that comes up is when the UI is migrated to use the API. In that case you won't be using #JsonIgnore, instead you will be using Json Views.
You can create classes representing specific views on your data and use them to tag your attributes with #JsonView(MyView.class). Finally, you can serialize your beans using objectMapper.writeValueUsingView(out, beanInstance, MyView.class);
In your case you could create an view class MyAPIView and annotate all fields but SHOW_IMAGE_FLAG with #JsonView(MyAPIView.class) (Note MyAPIView is an empty class used for tagging purposes, with no logic nor attributes).
If you call objectMapper.writeValueUsingView(out, beanInstance, MyAPIView.class); you wont serialize the SHOW_IMAGE_FLAG attribute. If you call objectMapper.writeValue(out, beanInstance) you will serialize the attribute.
You must determine at runtime the view to be used. If you are using OAuth you could select view depending on the connected client.
Eventually, you can create several views and apply inheritance. Take a look at jacksons doc.
I ended up with a config table for items called ITEM_CONFIG (ITEM_ID, UI_PROPERTIES)
On the UI_Properties I save a JSON string, which is mapped to a String propertie on the DAO model, but as a HashMap<String, Object> on the service model.
I have a converter that maps the value from the dao model to the hasmap on the service object, "automatically".
On the controller (in the BaseController, parent of every WebController [not rest]), I added a method to get the config from the ItemConfigService and then set the value on the response (Model in SpringMVC) using the hasmap key as the parameter and the value as the parameter value.
This is working very clean and we haven't had any issues since last week.

Intent of Spring form command

Spring's form controller (such as SimpleFormController or BaseCommandController) uses commands to pass data between the HTML form and controller. My question is, is it common practice to use the backing model as the command itself? Or is it common to create a separate command with correspond attributes to those in the backing model.
My issue is that to use the backing model as the command, property editors are necessary for conversion of non-string attributes. Imagine a data model with many non-string strongly typed custom field types. On a form submission, property editor does the conversion before the validator is called. If the type conversion is not possible (user input error), then the validator never gets a chance to provide a detailed error message. All that's displayed on the HTML form is a generic error message. See my related Stackoverflow question.
The alternative is to create a separate command that duplicates each field in the backing model, but as a string. In this way the validator can validate the string representation of each field. The controller's onSubmit is then responsible for converting the text-based command to the backing model. From my research of Spring this appears to be intended usage. My hesitation to go down this path is the cumbersome manner in which a separate command needs to be created for each data model. Then there's the added work having to marshal between the command and the data model. It's so much more convenient to have the form directly edit the backing model and use property editors to do the conversion. The problem then is validation.
So I'm curious how others approach the issue of form-based editing of models that contain custom typed non-string fields.
I'd recommend that you look into the Spring binding and validation API. Bind the form elements into the objects that the service layer needs and have the controller pass them along.
My preference is to bind directly to business objects and not create DTOs just for the sake of the web tier. I don't like parallel hierarchies.
IMHO this boils down to how you want to design your domain classes. I prefer to design 'em qiute strict by not even allowing setting inapropriate values etc. This does not combine very well with the way Spring handles binding and validation.
As I want to avoid weakening my domain model I tend to use DTOs as command objects as typically the presentation gets a slightly different view on the domain objects anyway. The classic example is a User domain class that carries a password. In the presentation layer you typically would want to let the actual user the password twice and compare those values in validation step. Only if they match correctly the data would be bound to the domain class.
Might introduce a little overhead but allows to cleanly separate domain/application layer from the view.

Categories