Regarding Events in Openbravo onSave need to get an client and set it into other class object - events

Here My code
Need to populate it from a class and then set in to another class especially all columns in product to product detail (Some How i managed other but My Problem is regarding Client. It is not showing anything)
public void onSave(#Observes EntityNewEvent event) {
if (!isValidEvent(event)) {
return;
}
final Entity product_Shift =ModelProvider.getInstance().getEntity(OCAProducts.ENTITY_NAME);
ProductsDetails pd = OBProvider.getInstance().get(ProductsDetails.class);
final Property pro_client = product_Shift.getProperty(OCAProducts.PROPERTY_CLIENT);
pd.setClient((Client) event.getCurrentState(pro_client));
OBDal.getInstance().save(pd);
OBDal.getInstance().flush();

Getter and setter methods do not work in Openbravo event handlers. Check the document from Openbravo's wiki here.
An excerpt from the wiki page.
don't call setters on the Greeting instance itself, this does not work
because when the event has been broadcasted, Hibernate has already
read the state of the object. So you must change the value through the
special setCurrentState method
Example
event.setCurrentState(clientProperty, clientId);
event.setCurrentState(pro_client, clientID)

Related

Grail validate data already saved to database

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()

Something similar to Grails Domain properties field in Spring?

I have started a new project in Spring Boot after using Grails for 4 years.
In Grails I have used properties field of an instance of a domain class to update the associate row in a db table. The assignment of domain.properties was usually done inside a service.
The properties field was set with data coming from a web form.
This approach allows to update a domain instance with a single line, instead of writing n assignemnt, where n is the number of the attributes defined in the domain class.
Now the question.. there is something similar in Spring?
I would like to do something similar in Spring:
update(Long radioId,Map properties) {
// get the radio to be update from the db
Radio radio = getRadio(radioId)
radio.properties = properties
save(radio)
}
I add some detail,
My controller
public ModelAndView updateRadio(Radio radio) {
radioService.update(radio);
return new ModelAndView("redirect:/superadmin/radio/"+radio.getIdentifier()+"/zoom");
}
My Service
#Service
public class RadioService {
...
public void update(Radio radio) {
assert radio.getId() != null;
radioRepository.save(radio);
}
...
}
Now if the web form does not explicity send all the fields defined in Radio I have problem since I will loose the value of the field already stored.
If I could write somthing like that
public void update(Map radioProperties,Long radioId) {
Radio radio = radioRepository.findById(radioId);
radio.properties = radioProperties // only properties present in this map will be update (in grails)
radioRepository.save(radio);
}
it would be great.
In the latter method only the properties in the map (ence in the web form) will be updated, and the other store field of the radio instance will be untouched.
Take a look at Spring Data JPA, it can load domain objects by id, bind incoming request parameters to domain objects and also automagic you some CRUD repositories.

Using session objects from parent class in component

During my battle with tapestry 5 I created some setup which does not work, and I don't know why. I found few work-arounds, but still I would like to know why initial idea failed.
I have parent abstract page class with application-wide auth procedure:
public abstract class AuthPage {
#SessionState
protected UserAuth user;
public Object onActivate(){
if(user==null)
return LoginForm.class;
else if(user.getLoggedIn().equals(Boolean.FALSE))
return LoginForm.class;
else
return null;
}
}
Then I have index page class, using auth class as aprent:
public class Index extends AuthPage
{
}
This part works smoohtly - when user SSO is initialized then I got Index content, otherwise it goes to LoginForm. Now the problematic part - Index uses a layout component which takes care of showing personalized header and menu. Its logic looks like that:
public class Layout extends AuthPage
{
#Property
private Boolean loggedIn;
#Property
private String userName;
#SetupRender
public boolean checkNames(){
if(user==null){
loggedIn = false;
userName = "unlogged";
}
else if(user.getLoggedIn().equals(Boolean.FALSE)){
loggedIn=false;
userName = "unlogged";
}
else{
loggedIn = true;
userName = this.user.getUsername();
}
return true;
}
}
The idea was simple - session object user from AuthPage should be available in Layout, and used on setup-render stage to get user name and rising the flag for rendering menu etc. From my point of view everything should work, but in practice Layout class didn't get user object from session (despite that it was initialized for sure, because Index renders its content).
So my question is - why Layout class don't see UserAuth object stored in session, but gets it as null instead?
************ little update:
I've refactore layout to that shape:
public class Layout
{
#SessionState
protected UserAuth user;
#Property
private Boolean loggedIn;
#Property
private String userName;
#SetupRender
public boolean checkNames(){
if(user==null){
loggedIn = false;
userName = "unlogged";
}
else if(user.getLoggedIn().equals(Boolean.FALSE)){
loggedIn=false;
userName = "unlogged";
}
else{
loggedIn = true;
userName = this.user.getUsername();
}
return true;
}
}
and it works as I want - Layout (executet from Index page as component) takes user attribute from session, performs checkNames and sets up all properties properly. For me there is no technical difference between initial and second implementation, but somehow when user is defined in parent class is always set to null (no matter what is stored in session). The question is - why it works that way?
Layout is a component, not a page, and onActivate() is page event which won't be fired when the Layout component renders. For a component (Layout) to extend a page (AuthPage) does not make sense. I'm surprised that Tapestry allows it to tell the truth.
On another note, Tapestry has so many features (including filters, class transformations and mixins) that inheritance is almost always not required. Although quite complex, you might find the diagram at the bottom of this page useful. In particular you may be interested in the ComponentRequestFilters and PageRenderRequestFilters.
Here's a couple of options for securing pages:
Howard Lewis Ship's blog - Howard is the creator of Tapestry
Tynamo tapestry security
What version of tapestry are you using? In tapestry 5.3.1 and earlier, instance variables must be private. Only version 5.3.2+ supports protected and package private.
http://tapestry.apache.org/page-and-component-classes-faq.html#PageAndComponentClassesFAQ-Whydomyinstancevariableshavetobeprivate%3F
Ok, I solved the problem! Answer is a little bit unexpected for me, but well - everything seems to work fine now. The trick is the way I was refering to the user attribue ot AuthPage class. I used
this.user
to refere to it from child classes. It turned out that I've got it as null everywhere, even in pages (I had an impression that it worked correctly in Index page, but in fact it was just used in AuthPage class). The solution was to refere by:
super.user
When I switched to such referencing style suddenly every page and component started to work properly and got correct values from session. I'll just take it as it is, but if someone knows why it works that way and no other - I'll appreciate sharing this knowledge with me.

Am I using #ModelAttribute wrong in my Controller?

For years I have been using #ModelAttribute to create and initialize my command object like so:
#RequestMapping()
public String someHandler(#ModelAttribute("formBean") FormBean formBean) {
// Do something
}
#ModelAttribute("formBean")
public FormBean createFormBean() {
FormBean formBean = new FormBean();
// Do some sort of initialization
return formBean;
}
In this example, I have a handler in a Controller that needs a FormBean, and a "create" method that gives it one if one isn't already in the Model (or session, if using #SessionAttributes). So, when my someHandler() method is ran, the FormBean is already there and populated because my createFormBean() had already ran.
However, my colleague is claiming that, although this works just fine, that I am misusing the #ModelAttribute for a purpose it wasn't intended for, namely in the creation of the Command object. In his interpretation from the JavaDoc, you should only use #ModelAttribute to create static data, like items used to populate a dropdown list or such.
I know this works for creating and initializing my Command object quite well, but am I using this for a purpose it was not originally intended for? Am I breaking some cardinal rule here?
#ModelAttribute("formBean")
public FormBean createFormBean() {
FormBean formBean = new FormBean();
// Do some sort of initialization
return formBean;
}
This can be useful if you need to initialize model attribute before binding form values from view. For example, you can query object from database (to get available it in current session).
In other cases I prefer to use this method:
#RequestMapping
public String someHandler(final Model model) {
FormBean formBean = new FormBean();
// Do some sort of initialization
model.addAttribute("formBean", formBean);
}
I think it more clear to understand. But I don't think that you "breaking some cardinal rule here".

In Spring MVC 3, how do I bind an object to a query string when the query string parameters don't match up with the object fields?

A 3rd party is sending me part of the data to fill in my domain object via a query string. I need to partially fill in my domain object, and then have the user fill in the rest via a form. I don't have any control over the query string parameters coming in, so I can't change those, but I'd really like to be able to use Spring MVC's data binding abilities, rather than doing it by hand.
How can I do this?
To add some complication to this, some of the parameters will require extensive processing because they map to other objects (such as mapping to a user from just a name) that may not even exist yet and will need to be created. This aspect, I assume, can be handled using property editors. If I run into trouble with this, I will ask another question.
Once I have a partially filled domain object, passing it on to the edit view, etc. is no problem, but I don't know how to properly deal with the initial domain object population.
The only thing I have been able to come up with so far is to have an extra class that has it's properties named to match the inbound query parameters and a function to convert from this intermediary class to my domain class.
This seems like a lot of overhead though just to map between variable names.
Can you not just have the getter named differently from the setter, or have 2 getters and 2 setters if necessary?
private int spn;
// Standard getter/setter
public int getSpn() {
return spn;
}
public void setSpn(int spn) {
this.spn = spn;
}
// More descriptively named getter/setter
public int getShortParameterName() {
return spn;
}
public void setShortParameterName(int spn) {
this.spn = spn;
}
Maybe that is not standard bean convention, but surely would work?

Resources