Hi everyone; i am using a ManyToMany annotation on my program because i want the user to select as many element then add them to the collection; which works well but i noticed that on my main application it doesn't refresh the screen until i exit/save the transaction then come back to my application and then i can see the elements stored on the collection( this behaviour only appears on my main application) so i thought if i could save the collection and refresh the previous view that could help but i keep on getting the error impossible to execute add and refresh action:null.
I am trying basically to have a behaviour like the one we see with @ElementCollection with the features to allow the user to select mutliple transactions and add them all at once; below are my models and action:
@Entity
@Table(name="tprecon")
//@Tab(baseCondition="${tpref}!=''")
@View(name="Simple",members="id,matid,capdte,code,amount,tpref,detail,tpvouch,tptrntax")
public class ThirdParty{
and my action is :
package com.yourcompany.demorun.actions;
import org.openxava.actions.*;
public class AddAndRefresh extends AddElementsToCollectionAction {
@Override
public void execute() throws Exception {
super.execute(); // perform the add
the stack error: SEVERE: null
java.lang.NullPointerException
at org.openxava.actions.SaveElementInCollectionAction.isKeyIncomplete(SaveElementInCollectionAction.java:142)
at org.openxava.actions.SaveElementInCollectionAction.saveIfNotExists(SaveElementInCollectionAction.java:110)
at org.openxava.actions.AddElementsToCollectionAction.execute(AddElementsToCollectionAction.java:34)
at com.yourcompany.demorun.actions.AddAndRefresh.execute(AddAndRefresh.java:8)
at org.openxava.controller.ModuleManager.executeAction(ModuleManager.java:596)
at org.openxava.controller.ModuleManager.executeAction(ModuleManager.java:528)
at org.openxava.controller.ModuleManager.execute(ModuleManager.java:486)
at org.apache.jsp.xava.execute_jsp._jspService(execute_jsp.java:264)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:64)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:444)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:354)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:305)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:197)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:142)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:619)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:496)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:444)
at org.openxava.web.servlets.Servlets.getURIAsStream(Servlets.java:72)
at org.openxava.web.dwr.Module.getURIAsStream(Module.java:282)
at org.openxava.web.dwr.Module.request(Module.java:61)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.directwebremoting.impl.CreatorModule$1.doFilter(CreatorModule.java:172)
at org.directwebremoting.impl.CreatorModule.executeMethod(CreatorModule.java:184)
at org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:353)
at org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:306)
at org.directwebremoting.dwrp.BaseCallHandler.handle(BaseCallHandler.java:110)
at org.directwebremoting.servlet.UrlProcessor.handle(UrlProcessor.java:211)
at org.directwebremoting.servlet.UrlProcessor.handle(UrlProcessor.java:185)
at org.directwebremoting.servlet.DwrServlet.doPost(DwrServlet.java:144)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:555)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:197)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:142)
at org.openxava.web.filters.ContentSecurityPolicyFilter.doFilter(ContentSecurityPolicyFilter.java:56)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:142)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:88)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:90)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:935)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1833)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:975)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:493)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:834)
is there a way for me to achieve that features( having the user select mutliple values and add them all to the collection at one) without using @ManyToMany?
please help
It does not work because @AddAction is the action executed when the user click on Add in the button in the collection, not in the button in the dialog to finish the addition. That is @AddAction is the action that shows the dialog. So, it should not extend AddElementsToCollectionAction but GoAddElementsToCollectionAction.
On the other hand, why do you need to refine the standard add action? I don't understand well you point. Do you mean that when you add elements those elements are not displaying in the collection on close the dialog?
Help others in this forum as I help you.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Javier;
"Do you mean that when you add elements those elements are not displaying in the collection on close the dialog?"
Yes when i use the default add features the collection does not show the values until i save the transaction and then select the transaction to edit only at that time i can see the value on the collection please see attached images(you can see on the screenshot it say 2 where added to tprec2 but there is nothing on the collection until i exit and come back as in editing): below is the code of the program you can try it and see for yourself(the program should run from the batmst class):
package com.yourcompany.marketpro.model;
@Column(name="user_name",length=30)publicStringuser;@ColumnprivateIntegerbatchno;@NoModify@NoCreate@ManyToOne(fetch=FetchType.LAZY,optional=false)@DescriptionsList(descriptionProperties="postdesc")privatePosttypeposttype;@Column(name="capdte",length=12)privateDatecapdte;@NotNull(message="Batch Total Must Not be Null")@Column(name="battot")privateBigDecimalbattot;@NotNull(message="Input VAT Total Must Not be Null")@Column(name="inpvat")@Stereotype("MONEY")privateBigDecimalinpvat;@NotNull(message="Output VAT Total Must Not be Null")@Column(name="outvat")@Stereotype("MONEY")privateBigDecimaloutvat;@Column(name="pstdte",length=12)privateDatepstdte;@OneToMany(mappedBy="parent",cascade=CascadeType.ALL)privateCollection<Batdet>batdetails=newArrayList<Batdet>();publicIntegergetBatchno(){returnbatchno;}publicvoidsetBatchno(Integerbatchno){this.batchno=batchno;}publicStringgetUser(){returnuser;}publicvoidsetUser(Stringuser){this.user=user;}publicPosttypegetPosttype(){returnposttype;}publicvoidsetPosttype(Posttypeposttype){this.posttype=posttype;}publicDategetCapdte(){returncapdte;}publicvoidsetCapdte(Datecapdte){this.capdte=capdte;}publicBigDecimalgetBattot(){returnbattot;}publicvoidsetBattot(BigDecimalbattot){this.battot=battot;}publicBigDecimalgetInpvat(){returninpvat;}publicvoidsetInpvat(BigDecimalinpvat){this.inpvat=inpvat;}publicBigDecimalgetOutvat(){returnoutvat;}publicvoidsetOutvat(BigDecimaloutvat){this.outvat=outvat;}publicDategetPstdte(){returnpstdte;}publicvoidsetPstdte(Datepstdte){this.pstdte=pstdte;}publicCollection<Batdet>getBatdetails(){returnbatdetails;}publicvoidsetBatdetails(Collection<Batdet>batdetails){this.batdetails=batdetails;}
The user will definitely want to see which values were added to the list in order to amend them if necessary, that is why i was looking for a way to refresh the view maybe.
You're right, I tried your code and it fails. Please, add a bug with a link to this thread, so we can fix it for a future OpenXava release.
I note that when a edit an existing detail and try to add thirdparties to it, it works nicely, showing the details after adding them. So I think it fails because the detail is not saved yet, so the relation in database is not created yet, therefore the lines are not shown. This is the reason because they are shown when you edit the detail again (the detail already exist in db), and also because in that case the lines are shown when added too.
It means that you can solved your problem, before I could fix the bug, just creating the detail in database when you open the dialog to add lines. That is, create a @AddAction that refine the original add action to just create the current detail if it does not exist yet, before opening the dialog to add parties.
Try it and tell me how it is going.
Help others in this forum as I help you.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Javier,
I have added to the bug with the link to this thread.
"Try it and tell me how it is going"
that may be a little difficult based on the current setup as some information need to be provided by the user before creating the record, like matid; it is only after the user provide those , that he can add a third party and link it to the transaction
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Javier i have tried the implementation provided earlier it is saving it but unfortunately my view doesn't show it until i close the dialog and go back to the transaction just like before. please see below my action:
Hi Javier, apologies for delay, yes even when i go to another tab and come back to the third party tab i still dont see anything until i close/save the transaction then when i want to edit i can see the third party selected
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
As I said above, I reproduced the bug and you filled it. So the it's a bug with @ManyToMany that we'll fix in the feature. Unfortunately the trick of saving the record before does not work, maybe that is not the caus of the bug.
If you do a reload with the browser refresh button? Do the collections appear?
If after you close the dialog that the record, in your action do a getView().refresh()? Does it work.
If none of the above works, the solution is not to use @ManyToMany. You can turn @ManyToMany in @OneToMany creating an explicit entity to do the union (an entity with two @ManyToOne), with the same effect.
Help others in this forum as I help you.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi everyone; i am using a ManyToMany annotation on my program because i want the user to select as many element then add them to the collection; which works well but i noticed that on my main application it doesn't refresh the screen until i exit/save the transaction then come back to my application and then i can see the elements stored on the collection( this behaviour only appears on my main application) so i thought if i could save the collection and refresh the previous view that could help but i keep on getting the error impossible to execute add and refresh action:null.
I am trying basically to have a behaviour like the one we see with @ElementCollection with the features to allow the user to select mutliple transactions and add them all at once; below are my models and action:
import javax.persistence.*;
import org.openxava.annotations.;
import org.openxava.model.;
import lombok.*;
package com.yourcompany.demorun.model;
import java.math.*;
import javax.persistence.*;
import org.openxava.annotations.*;
import lombok.*;
@Entity
@Getter @Setter
@View(members="proId,productName,amount,description;")
public class Product {
}
package com.yourcompany.demorun.model;
import java.math.;
import java.util.;
import javax.persistence.*;
import org.openxava.annotations.*;
@Entity
@Table(name="tprecon")
//@Tab(baseCondition="${tpref}!=''")
@View(name="Simple",members="id,matid,capdte,code,amount,tpref,detail,tpvouch,tptrntax")
public class ThirdParty{
}
and my action is :
package com.yourcompany.demorun.actions;
import org.openxava.actions.*;
public class AddAndRefresh extends AddElementsToCollectionAction {
@Override
public void execute() throws Exception {
super.execute(); // perform the add
}
the stack error: SEVERE: null
java.lang.NullPointerException
at org.openxava.actions.SaveElementInCollectionAction.isKeyIncomplete(SaveElementInCollectionAction.java:142)
at org.openxava.actions.SaveElementInCollectionAction.saveIfNotExists(SaveElementInCollectionAction.java:110)
at org.openxava.actions.AddElementsToCollectionAction.execute(AddElementsToCollectionAction.java:34)
at com.yourcompany.demorun.actions.AddAndRefresh.execute(AddAndRefresh.java:8)
at org.openxava.controller.ModuleManager.executeAction(ModuleManager.java:596)
at org.openxava.controller.ModuleManager.executeAction(ModuleManager.java:528)
at org.openxava.controller.ModuleManager.execute(ModuleManager.java:486)
at org.apache.jsp.xava.execute_jsp._jspService(execute_jsp.java:264)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:64)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:444)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:354)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:305)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:197)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:142)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:619)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:496)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:444)
at org.openxava.web.servlets.Servlets.getURIAsStream(Servlets.java:72)
at org.openxava.web.dwr.Module.getURIAsStream(Module.java:282)
at org.openxava.web.dwr.Module.request(Module.java:61)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.directwebremoting.impl.CreatorModule$1.doFilter(CreatorModule.java:172)
at org.directwebremoting.impl.CreatorModule.executeMethod(CreatorModule.java:184)
at org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:353)
at org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:306)
at org.directwebremoting.dwrp.BaseCallHandler.handle(BaseCallHandler.java:110)
at org.directwebremoting.servlet.UrlProcessor.handle(UrlProcessor.java:211)
at org.directwebremoting.servlet.UrlProcessor.handle(UrlProcessor.java:185)
at org.directwebremoting.servlet.DwrServlet.doPost(DwrServlet.java:144)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:555)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:197)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:142)
at org.openxava.web.filters.ContentSecurityPolicyFilter.doFilter(ContentSecurityPolicyFilter.java:56)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:142)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:88)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:90)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:935)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1833)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:975)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:493)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:834)
is there a way for me to achieve that features( having the user select mutliple values and add them all to the collection at one) without using @ManyToMany?
please help
Hi Kabongo,
It does not work because @AddAction is the action executed when the user click on Add in the button in the collection, not in the button in the dialog to finish the addition. That is @AddAction is the action that shows the dialog. So, it should not extend AddElementsToCollectionAction but GoAddElementsToCollectionAction.
Look at this doc that explains with detail how to refine add action for a collection:
https://www.openxava.org/OpenXavaDoc/docs/references-collections_en.html#refining-the-list-for-adding-elements-to-a-collection
On the other hand, why do you need to refine the standard add action? I don't understand well you point. Do you mean that when you add elements those elements are not displaying in the collection on close the dialog?
Help others in this forum as I help you.
Hi Javier;
"Do you mean that when you add elements those elements are not displaying in the collection on close the dialog?"
Yes when i use the default add features the collection does not show the values until i save the transaction and then select the transaction to edit only at that time i can see the value on the collection please see attached images(you can see on the screenshot it say 2 where added to tprec2 but there is nothing on the collection until i exit and come back as in editing): below is the code of the program you can try it and see for yourself(the program should run from the batmst class):
package com.yourcompany.marketpro.model;
import java.math.;
import java.util.;
import javax.persistence.;
import javax.validation.constraints.;
import org.openxava.annotations.;
import org.openxava.model.;
@Entity
@Table( name="batmst")
@View(members="Batch[#" +
"posttype, capdte, pstdte; battot, inpvat, outvat;" +
"batdetails]"
)
@View(name="Simple", members="batchno, battot, pstdte")
public class Batmst extends Identifiable{
}
package com.yourcompany.marketpro.model;
import java.math.;
import java.util.;
import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.Table;
import org.hibernate.annotations.;
import org.openxava.annotations.;
import lombok.*;
@Entity
@Table(name="batdet")
@View(members="optionFromParent; matters;" +
"Transaction{" +
"capdte;" +
"detamt;" +
"details; "+
"},"
@Getter @Setter
public class Batdet{
// @AddAction("Batdet.goAddThirdParty")
}
package com.yourcompany.marketpro.model;
import java.math.;
import java.util.;
import javax.persistence.*;
import org.openxava.annotations.*;
@Entity
@Table(name="tprecon")
@View(name="Simple",members="id,matid,capdte,code,amount,tpref,detail,tpvouch,tptrntax")
public class ThirdParty{
}
package com.yourcompany.marketpro.model;
import javax.persistence.*;
import org.openxava.annotations.*;
@Entity
@Table( name="posttype")
public class Posttype {
}
The user will definitely want to see which values were added to the list in order to amend them if necessary, that is why i was looking for a way to refresh the view maybe.
Hi Kabongo,
You're right, I tried your code and it fails. Please, add a bug with a link to this thread, so we can fix it for a future OpenXava release.
I note that when a edit an existing detail and try to add thirdparties to it, it works nicely, showing the details after adding them. So I think it fails because the detail is not saved yet, so the relation in database is not created yet, therefore the lines are not shown. This is the reason because they are shown when you edit the detail again (the detail already exist in db), and also because in that case the lines are shown when added too.
It means that you can solved your problem, before I could fix the bug, just creating the detail in database when you open the dialog to add lines. That is, create a @AddAction that refine the original add action to just create the current detail if it does not exist yet, before opening the dialog to add parties.
Try it and tell me how it is going.
Help others in this forum as I help you.
Hi Javier,
I have added to the bug with the link to this thread.
"Try it and tell me how it is going"
that may be a little difficult based on the current setup as some information need to be provided by the user before creating the record, like matid; it is only after the user provide those , that he can add a third party and link it to the transaction
Hi Kabongo:
In your @AddAction call to MapFacade.create before call to super, in this way:
Because MapFacade.create() validates before savings, so it will not continue to super.execute() and the validation errors will be shown to the user.
Help others in this forum as I help you.
Hi Javier i have tried the implementation provided earlier it is saving it but unfortunately my view doesn't show it until i close the dialog and go back to the transaction just like before. please see below my action:
import org.openxava.actions.;
import org.openxava.model.;
public class AddAndRefresh extends AddElementsToCollectionAction {
}
Hi Kabongo,
If you, without close the dialog, go to Transaction tab, and then go back to Third parties tab, are the records displayed?
Help others in this forum as I help you.
Hi Javier, apologies for delay, yes even when i go to another tab and come back to the third party tab i still dont see anything until i close/save the transaction then when i want to edit i can see the third party selected
Hi Kabongo,
As I said above, I reproduced the bug and you filled it. So the it's a bug with @ManyToMany that we'll fix in the feature. Unfortunately the trick of saving the record before does not work, maybe that is not the caus of the bug.
If you do a reload with the browser refresh button? Do the collections appear?
If after you close the dialog that the record, in your action do a getView().refresh()? Does it work.
If none of the above works, the solution is not to use @ManyToMany. You can turn @ManyToMany in @OneToMany creating an explicit entity to do the union (an entity with two @ManyToOne), with the same effect.
Help others in this forum as I help you.