Grail validate data already saved to database - validation

I have this really complicated form. All the fields must be filled, but the process of filling can be saved and leter continued. So what i need s that when finally confirm is pressed, all the data get validated. But because it is already saved to database calling validate() wont work. I save the data by douing save(validate:false), because i dont need validation when the work is still in progremm.
How can i validate data that has already been saved to database ? Do i have to do it manually?

What happens when you validate an already persisted object?
Is there a way to make it appear dirty after retrieving and before validating?

I have edited the answer to explain form encapsulation in more detail, typically maybe from a tier step process of form input or more complex iterated objects that needs to be elsewhere. To begin if all you need is a one step that captures a variety of information and you are happy to then process all that manually and store in different classes on mass params dump then look into jquery-ui tabs. If you choose to use the dynamic feature of tabs i.e. <li><a href="someurl">click</li> which then loads content dynamically to a given tab then that would also cover single forms that are outside or maybe if you prefer more complex within DOM.
Anyhow the reason for my edit wasn't above it is for something a little more complex that captures multi tier forms.
So you had step 1 that sent params through to a controller that then passed those params to a new gsp or maybe even an iteration of something that belongs to another totally different object within the form.
Typically you would end up with:
<g:form action=myDomain" action="doThis">
<!-- this is some iteration that belongs to some other class outside of what i am actually trying to do: -->
<g:each in="someObject" var="p">
<g:hiddenField name="form1.firstName" value="${p.firstName}"/>
<!-- in this case hidden -->
<g:hiddenField name="form1.surName" value="${p.surName}"/>
</g:each>
<!-- this is my actual form -->
<g:textField name="username" />
</g:form>
When form is submitted to a controller
Class MyDomainController {
def doThis(MyBean bean) {
save(bean)
}
}
//this be in src/main/groovy
import grails.validation.Validateable
//important for some reason it needs entire collections
// have had issues initialising it without .*
import org.apache.commons.collections.*
Class MyBean implements Validateable {
//this is capturing the current form fields
String username
//This is now collecting our form1 fields
List<MyDetailsBean> form1 = ListUtils.lazyList([], { new MyDetailsBean() } as Factory)
//if that had been 1 instance of it or like as mentioned passed from pervious form and called form2
MyDetailsBean form2
static constraints={
username(nullable:false) //, validator: checkSomething)
}
}
This is again in src/main/groovy and was used to originally collect each iteration of an object:
import grails.validation.Validateable
Class MyDetailsBean implements Validateable {
String firstName
String surName
}
I have updated the answer since i suggested encapsulating the object in a bean without any details of how one would go about doing such a thing. I hope above is clear. It is all on the fly but if tested hope it all works as explained above.
TO add after next update explained form2 example. to finally validate both sets you call
if (bean.validate() && bean.form2.validate()) {
//all good
}
Because you are binding it to another validation class the rules of that class can now be applied as part of validation process.
Old answer
Quite simply put it is on the db why on earth would you want to validate a validated input. Anyhow the work around is a validation bean in Grails 2 src/groovy/package which is #Validateable or
Grails 3 : src/main/groovy/package which implements Validateable
class MyDmainBean {
// must declare id
def id
// Then each object in your real domain class
static constraints = {
id (nullable:true,bindable:true)
importFrom MyDomainClass//, exclude: ['field1']
//field 1 is not included but if field 1 was integer
// in actual domain class and BigDecimal in bean
//then exlude it since it won't bind
}
def formatObject(MyDomainClass domain) {
id=domain.id
..
}
}
Now you can call
MyDomain record = MyDomain.get(0L)
MyDmainBean bean = new MyDmainBean().formatObject(record)
bean.validate()

Related

Spring boot + JPA(Hibernate) Edit partial entity fields

all.
I have following simple form in which I want to edit the entity. The problem is that I have some fields which I don't want to be edited. For example (Image file path).
As it is now, I have the service method -
public void addOrModifyLayout(Layout layout){
if(layout.getId() == null){
layoutRepository.save(layout);
}
else {
Layout modifiedLayout = new Layout();
modifiedLayout.setId(layout.getId());
modifiedLayout.setName(layout.getName());
modifiedLayout.setStatus(layout.getStatus());
modifiedLayout.setExhibitor(layout.getExhibitor());
layoutRepository.save(modifiedLayout);
}
}
As you can see, every field that I want to be able to be edited, I should explicitly put it in the service. Can I use some mapper or trick to update only some fields that are in the view (form) ? How you handle this kind of issues?
You can either
store all the entity fields in hidden inputs (e.g. imageFilePath hidden input). So you can store on UI all the entity fields and get them back to assign to the entity.
OR
Avoid new entity creation but retrieve existing one and fill only necessary fields.
Layout modifiedLayout = layoutRepository.getById(layout.getId());
modifiedLayout.setName(layout.getName());
modifiedLayout.setStatus(layout.getStatus());
modifiedLayout.setExhibitor(layout.getExhibitor());
layoutRepository.save(modifiedLayout);

How to correctly initialize an object that have to contain the data retrieved by 2 methods of my controller in this Spring MVC application?

I am pretty new in Spring MVC and I have the following doubt about how correctly achieve the following task.
I am working on a web application that implement a user registration process. This registration process is divided into some consecutive steps.
For example in the first step the user have to insert a identification code (it is a code that identify uniquely a user on some statal administration systems) and in the second step it have to compile a form for his personal data (name, surname, birth date, and so on).
So, actually I have the following controller class that handle these steps:
#Controller
public class RegistrazioneController {
#Autowired
private LoadPlacesService loadPlacesService;
#RequestMapping(value = "/iscrizioneStep1")
public String iscrizioneStep1(Model model) {
return "iscrizioneStep1";
}
#RequestMapping(value = "/iscrizioneStep2", method=RequestMethod.POST)
public String iscrizioneStep2(Model model, HttpServletRequest request, #RequestParam("cf") String codicFiscale) {
System.out.println("INTO iscrizioneStep2()");
//String codicFiscale = request.getParameter("cf");
System.out.println("CODICE FISCALE: " + codicFiscale);
model.addAttribute("codicFiscale", codicFiscale);
return "iscrizioneStep2";
}
#RequestMapping(value = "/iscrizioneStep3", method=RequestMethod.POST)
public String iscrizioneStep3(#ModelAttribute("SpringWeb")Step2FormCommand step2Form, ModelMap model, HttpServletRequest request) {
System.out.println("INTO iscrizioneStep3()");
System.out.println("NOME: " + step2FormCommand.getName());
return "iscrizioneStep3";
}
Into the iscrizioneStep2() it is retrieved the first code (#RequestParam("cf") String codicFiscale).
Into the iscrizioneStep3() it is retrieved a command object containing the data inserted into the form of the view in which this form was submitted, this one:
#ModelAttribute("SpringWeb")Step2FormCommand step2FormCommand
It works fine.
Now my problem is that I have another object named Step3View that have to be initialized with the aggregation of the #RequestParam("cf") String codicFiscale object retrieved into the iscrizioneStep2() method and the #ModelAttribute("SpringWeb")Step2FormCommand step2FormCommand retrieved into the iscrizioneStep3() method.
This Step3View class simply contain the String codicFiscale and all the fields of the Step2FormCommand class.
Now my doubts are: what is the best way to handle this situation? Where have I to declare this Step3View object? at controller level? (so I can use it in all my controller methods?). Have I to annotate this class with #Component (or something like this) to inject it in my controller?
What is the best solution for this situation?
I think in order to get an answer you need to understand the question and ask the right question. I think your question is "how do I pass a parameter from one page to another page in SpringMVC?". You specifically want to know how to pass the "cf" param, but readers here will tend to pass over questions that are too specific because it takes too much time to figure out what you want.
In answer to that, see Spring MVC - passing variables from one page to anther as a possible help.
Also, there are many good answers about this question for JSP in general, which can be worked into the SpringMVC architecture. See How to pass value from one jsp to another jsp page? as a possible help.

How to control two operations for same url in Spring mvc?

Consider the following problem.
The user has chosen to create a document by clicking on the Create document and then he writes data into the document. The url for creating the document is /document/save.
For the subsequent write up, the existing document must be saved instead of creating a new one.
Here is my code for that.
#Controller
public MyController implements Controller, TemplateTypeAware
{
#RequestMapping("/document/save")
public String saveOrCreateDocument(#ModelAttribute DocumentWrapper wrapper, ModelAndView m)
{
if(m.getModel().get("document_id")==null)
{
Document doc=createDocument(wrapper);
m.addObject("document_id",doc.getId());
}
else
{
saveDocument(m.getModel().get("document_id"), wrapper);
}
return documentView;
}
}
Template:
<form>
<input type="hidden" name="document_id" th:value="*{document_id}"/>
<!-- other fields -->
</form>
The problem here is, I am getting document_id always null. Is there any work around for this problem?
Thanks in advance. Hope you will reply as soon as possible.
Form fields will be automatically bound to your DocumentWrapper fields if they have matching names, that means DocumentWrapper needs a field named document_id, otherwise the document_id request parameter won't be bound to your object.
Model attributes will be exposed to the view, at this point the model will be empty, you can add attributes in your handler method and they will become in your view, but request parameters won't be in the model. That explains why you always get null.
If you just need the document_id parameter, use #RequestParam:
#RequestMapping("/document/save")
public String saveOrCreateDocument(#RequestParam("document_id") Long documentId, Model m) {
...
}
Please refer to the binding section of Spring MVC: http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-requestparam

jsf 2: how to make Primefaces line chart change every 1 second?

Basically, I want to implement a webpage using Primefaces line chart that can change every one second.
In my managed bean, I get, say 100 data from my database. Instead of populating the line chart all at once, I want to display them like a data wave, so that these 100 data can be shown in 100 seconds.
How can I implement this?
You should get 100 data from DB and store them in a list let say main list, and there should be one more list which will be refreshed every one second and the current element of main list will be appended to second list . Sth. like that:
#ManagedBean
#ViewScoped
public class DataBean {
private ArrayList<Data> mainList;//fill this from DB via seperate DAO class
private ArrayList<Data> viewList;
public int counter;
//getter and setters
public void refreshList() {
viewList.add(mainList.get(counter);
counter++;
}
}
And at the view layer you should call refreshList method periodically of course this can be done with p:poll or p:remoteCommand. RemoteCommand needs to be called more than once via JS code, it's like:
jQuery(document).ready(function () {
setInterval("updateChart", 1000);//every 1 sec
});
And this func. will call the p:remoteCommand which is named as updateChart:
<p:remoteCommand name="updateChart" actionListener="#{dataBean.refreshList}"
update="myChart"/>
myChart is the client id of your p:lineChart component you have to give the exact ID, you can detect it via your browser's developer settings.
And remember that this is not the exact implementation there can be errors, and p:lineChart expects model classes instead arrayLists, I've never used chart components but I'm assuming series similar to lists. Hope this can guide you.

What, exactly, does a modelbinder do? How to use it effectively?

I was researching something and came across this blog post at buildstarted.com about model binders. It actually works pretty darn well for my purposes but I am not sure exactly whats going on behind the scenes. What I did was create a custom ModelBinder called USerModelBinder:
public class UserModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
ValueProviderResult value = bindingContext.ValueProvider.GetValue("id");
MyEntities db = new MyEntities();
User user = db.Users.SingleOrDefault(u => u.UserName == value.AttemptedValue);
return user;
}
}
Then in my Global.asax.cs I have:
ModelBinders.Binders.Add(typeof(User), new UserModelBinder());
My understanding is that using the model binder allows me to NOT have to use the following lines in every controller action that involves a "User". So instead of passing in an "id" to the action, the modelbinder intercepts the id, fetches the correct "item"(User in my case) and forwards it to the action for processing.
MyEntities db = new MyEntities();
User user = db.Users.SingleOrDefault(u => u.UserName == value.AttemptedValue);
I also tried using an annotation on my User class instead of using the line in Global.asax.cs:
[ModelBinder(typeof(UserModelBinder))]
public partial class User
{
}
I'm not looking for a 30 page white paper but I have no idea how the model binder does what it does. I just want to understand what happens from when a request is made to the time it is served. All this stuff "just working" is not acceptable to me, lol. Also, is there any difference between using the annotation versus adding it in Global.asax.cs? They seem to work the same in my testing but are there any gotchas?
Usually the Model Binder (in MVC) looks at you Action method and sees what it requires (as in, the objects types). It then tries to find the values from the HTTP Request (values in the HTTP Form, QueryString, Json and maybe other places such as cookies etc. using ValueProviders). It then creates a new object with the parameters that it retrieves.
IMO What you've done is not really "model binding". In the sense that you've just read the id and fetched the object from the DB.
example of usual model binding:
// class
public class SomeClass
{
public int PropA {get;set;}
public string PropB {get;set;}
}
// action
public ActionResult AddSomeClass(SomeClass classToBind)
{
// implementation
}
// pseudo html
<form action="">
<input name="PropA" type="text" />
<input name="PropB" type="text" />
</form>
if you post a form that contains the correct values (lets say you post a form with PropA and PropB ) the model binder can identify that you've sent those values in the form and build a SomeClass object.
If you really want to create a real working example you should use a strongly typed View and use HtmlHelper's EditorFor (or EditorForModel) to create all the correct names that MVC needs.
--
for reference MVC's default binder is the DefaultModelBinder, and some (there are more, you can look around in the System.Web.Mvc namespace) ValueProviders that it uses by default are the FormValueProvider and the QueryStringValueProvider
So, as I already said, how this basically works is that the default model binder reads the model that the action is recieving (say SomeClass in the example) reads what are the values that it can read (say PropA and PropB) and asks the ValueProviders for the correct values for the properties.
Also, if I recall correctly, you can also see the value providers in runtime using the ValueProviderFactories static class.
A ModelBinder looks at the arguments of the selected Controller action's method signature, then converts the values from the ValueProviders into those arguments.
This happens when the ControllerActionInvoker invokes the action associated with the ControllerContext, because the Controller's Execute() method told it to.
For more about the ASP.NET MVC execution process, see Understanding the MVC Application Execution Process

Resources