13 Replies Latest reply on Oct 27, 2010 8:24 AM by Leo van den berg

    Update in Database without .merge operation

    Ankita Singh Newbie
      Hi All,
             I am facing one problem at the time of updating values in database.If the validation fails,its still updating the database.

      The Code For this One which I have written :
      For .xhtml file:

      <s:decorate id="dtExpiryDateCertificate"
                                                             template="../layout/edit.xhtml">
                                                             <ui:define name="label">#{messages.lblDtExpiryDate}</ui:define>
                                                             <rich:calendar id="dtExpiryDateCertificateId"
                                                                  styleClass="shortInput" value="#{certificate.dtExpiryDate}"
                                                                  datePattern="dd/M/yy hh:mm a" event="onblur" />
                                                        </s:decorate>


      For Action Class:

      @Begin(join = true)
           public void renewCertificateUpdate() {
                long startDate = certificate.getDtStartDate().getTime();
                long expiryDate = certificate.getDtExpiryDate().getTime();

                log.info("Start Date Of Current Certificate ==" + startDate);
                log.info("End Date Of the Certificate ==" + expiryDate);

                boolean validationExpiryDateFailed = false; 
                if (startDate > expiryDate) {
                     log.info("Error message for start Date is greater than ExpiryDate");
                     facesMessages.addToControlFromResourceBundle("commonPanel",
                               "message.required.certificate.startDateExpiryDateRenew");
                     validationExpiryDateFailed = true;
                }
                if (!validationExpiryDateFailed) {
                     certificate = tenantEntityManager.merge(certificate);

                     fetchCertificateDetails();
                     overlayVisible = false;
                     facesMessages
                               .addFromResourceBundle("message.certificate.renew.successful");
                } else {
                     log.info("Overlay Visible value " + overlayVisible);
                     log.info("Enter in not updating part");
                     ctx.setRollbackOnly();
                }
                log.info("End of renew certificate functionality");
                log.info("value of overlay visible at the end of " + overlayVisible);

           }

      Thanks in advance.
        • 1. Re: Update in Database without .merge operation
          Leo van den berg Master

          Hi,


          First try to simplify your code a bit. The boolean value is not necessary. So if you see the error message the merge is not reached.


           if (startDate > expiryDate) {
             log.info("Error message for start Date is greater than ExpiryDate");
             facesMessages.addToControlFromResourceBundle("commonPanel",
               "message.required.certificate.startDateExpiryDateRenew");
            } else {
             certificate = tenantEntityManager.merge(certificate);
          
             fetchCertificateDetails();
             overlayVisible = false;
             facesMessages
               .addFromResourceBundle("message.certificate.renew.successful");
            } 



          HOWEVER:


          Because you added the value already to the bean and the method is probably Transactional and you probably have not set the Manual flush, the entitymanager will see that there are changes and the value will be saved. Try using the Manual flushing mode and use the flush method and not the merge (which results in auto-save).


          Leo

          • 2. Re: Update in Database without .merge operation
            Ankita Singh Newbie

            Hi,
                 Thanks for the quick response.I have changed my code and set manual flush .but still getting the grid updated without calling merge operation.



            @Begin(join = true, flushMode = FlushModeType.MANUAL)
                 public void renewCertificateUpdate() {
                      long startDate = certificate.getDtStartDate().getTime();
                      long expiryDate = certificate.getDtExpiryDate().getTime();
                      if (startDate > expiryDate) {
                           log.info("Error message for start Date is greater than ExpiryDate");
                           facesMessages.addToControlFromResourceBundle("commonPanel",
                                     "message.required.certificate.startDateExpiryDateRenew");
                      } else {
                           certificate = tenantEntityManager.merge(certificate);
                           fetchCertificateDetails();
                           overlayVisible = false;
                           facesMessages
                                     .addFromResourceBundle("message.certificate.renew.successful");
                      }
                 }|



            • 3. Re: Update in Database without .merge operation
              Leo van den berg Master

              Hi,


              show the piece of code where and how you call the renewCertificateUpdate method and how you enter the page /select the certificate.


              Leo

              • 4. Re: Update in Database without .merge operation
                Ankita Singh Newbie

                Hi,
                Code which i have written for calling renewCertificate method in .xhtml file is:




                <h:panelGrid columns="1" columnClasses="name" rendered="#{manageCertificate.formToLoad=='renewCertificateForm'}"
                                                   styleClass="panelGrid">
                                                   <s:div styleClass="modalPanel-panelGrid-container-div">
                                                        <s:decorate id="dtEditExpiryDateCertificate"
                                                             template="../layout/edit.xhtml">
                                                             <ui:define name="label">#{messages.lblDtExpiryDate}</ui:define>
                                                             <rich:calendar id="dtExpiryDateCertificateId"
                                                                  styleClass="shortInput" value="#{certificate.dtExpiryDate}"
                                                                  datePattern="dd/M/yy hh:mm a" event="onblur" />
                                                        </s:decorate>
                                                        <h:panelGrid width="330" columns="2" style="text-align: center;">
                                                             <a:commandButton id="okrenew" value="#{messages.btnRenew}"
                                                                  reRender="commonPanel" style="margin-left: 4px;"
                                                                  action="#{manageCertificate.renewCertificateUpdate}"
                                                                  onclick="this.disabled=true"
                                                                  oncomplete="Richfaces.hideModalPanel('commonMp')" />
                                                             <a:commandButton id="cancelrenew" value="#{messages.btnCancel}"
                                                                  style="margin-left: 4px;"
                                                                  action="#{manageCertificate.closeLayer}"
                                                                  oncomplete="Richfaces.hideModalPanel('commonMp')" />
                                                        </h:panelGrid>
                                                   </s:div>
                                              </h:panelGrid>








                • 5. Re: Update in Database without .merge operation
                  Leo van den berg Master

                  Hi,


                  The Begin has no use at that specific location. In other words yhe conversation is started, but it assume it is not using the entitymanager in Manual flush mode.


                  Try using the page with an already long.running conversation and setting the manual flush mode there.
                  Put the right page name in view-id and add this to pages.xml




                  <page view-id="yourpageName.xhtml"  >
                       <begin-conversation join="true" flush-mode="manual"/>
                  </page>
                  




                  Leo

                  • 6. Re: Update in Database without .merge operation
                    Ankita Singh Newbie

                    Hi,
                         I have written the same piece of code in pages.xml but same thing is happening.


                    Code Of pages.xml is


                    <page view-id="/certificate/manageCertificate.xhtml" action="#{manageCertificate.searchAllCertificates()}">
                              <begin-conversation join="true" flush-mode="manual"/>
                              <param name="orderBy" value="#{manageCertificate.orderBy}" />
                              <param name="sortOrder" value="#{manageCertificate.sortOrder}" />
                              <param name="requestedPage" value="#{manageCertificate.requestedPage}" />
                              <param name="certificateTypeId" value="#{manageCertificate.certificateTypeId}" />
                              <param name="certificateTitle" value="#{manageCertificate.certificateTitle}" />
                         </page>



                    • 7. Re: Update in Database without .merge operation
                      Ankita Singh Newbie

                      Hi,
                        
                      Update is working fine,but main problem occurs when we are validating two date fields in server side as i mentioned above in action class.So at that point of time ,if validation failed,it does not show any error message and also update the Date filed.
                        




                      • 8. Re: Update in Database without .merge operation
                        Leo van den berg Master

                        Hi,


                        Check if the insert is happening before you press the button (when you enter the date). Set the show
                        sql flag in hibernate and leave the datebox. If your DB-insert takes place there, than the Calendar should surpress updates by using the ajaxSingle is true. At the same time this is VERY strange behaviour, because when you have a Manual flush mode active there shouldn't be ANY DB-activity until you command that with the flush-method.


                        The entitymanager has a getFlushMode method, so check to see what is its value when the manageCertificate.renewCertificateUpdate method is entered.


                        Leo

                        • 9. Re: Update in Database without .merge operation
                          Leo van den berg Master

                          Hi,


                          that makes more sense!


                          Your date value are not available at the time you enter the method. The Calendar component has some strange behaviour there. Put an additional ahjax-support tag inside the calendar with the same onblur and aajaxSingle true. That will possibly solve your problem.


                          Leo

                          • 10. Re: Update in Database without .merge operation
                            Ankita Singh Newbie

                            Hi,
                               Same thing is happening after putting a support
                            Code is


                            <s:decorate id="dtEditExpiryDateCertificate" template="../layout/edit.xhtml">                         
                            <ui:define name="label">#{messages.lblDtExpiryDate}</ui:define>
                            <rich:calendar id="dtExpiryDateCertificateId"
                            styleClass="shortInput" value="#{certificate.dtExpiryDate}"
                            datePattern="dd/M/yy hh:mm a" event="onblur">
                                 <a:support event="onblur" ajaxSingle="true" />
                            </rich:calendar>
                                                                    </s:decorate>
                            



                            • 11. Re: Update in Database without .merge operation
                              Leo van den berg Master

                              Hi,


                              check if the DB contains the changed value after leaving the calendar, so don't press any button and check the DB-content.


                              Leo

                              • 12. Re: Update in Database without .merge operation
                                Ankita Singh Newbie

                                Hi,
                                   The grid and database both are updating at the time when we click on the renew button.Its entering in the validation false part ,still its updating the grid and database.


                                Code where it goes if validation fails is


                                public void renewCertificateUpdate() {
                                          long startDate = certificate.getDtStartDate().getTime();
                                          long expiryDate = certificate.getDtExpiryDate().getTime();
                                          if (startDate > expiryDate) {
                                               log.info("Error message for start Date is greater than ExpiryDate");
                                               facesMessages.addToControlFromResourceBundle("commonPanel",
                                                         "message.required.certificate.startDateExpiryDateRenew");
                                               ctx.setRollbackOnly();
                                          } else {
                                               certificate = tenantEntityManager.merge(certificate);
                                               tenantEntityManager.flush();
                                               fetchCertificateDetails();
                                               overlayVisible = false;
                                               facesMessages
                                                         .addFromResourceBundle("message.certificate.renew.successful");
                                          }
                                     }



                                I am also trying one more thing sessionContext setRollBack method,but the problem with this one is :its not updating the database ,but updates the Certificate Grid which we are refreshing aftyer successful renew of Certificate,means Expiry Date is updating in the Grid.

                                • 13. Re: Update in Database without .merge operation
                                  Leo van den berg Master

                                  Hi,


                                  Again, your database is functioning in auto-commit, as adviced before check the flush mode (should be manual for this kind of application.


                                  To check this: Place different log.info statements in the method and set the show-sql property to see the exact timuing when things happen.



                                  Leo