0 Replies Latest reply on Jun 24, 2008 3:07 PM by dahm

    Seam + Hibernate + Richfaces pickList behaves badly

    dahm

      Hi,


      I noticed a strange behavior and am not sure which of the three above mentioned components is responsible for it...


      We've got two classes with a ManyToMany association between them:


      @Entity
      public class MobilePhone extends TerminalDevice {
      ...
        @ManyToMany(mappedBy = "mobilePhones")
        private final List<PaymentAccount> paymentAccounts = new ArrayList<PaymentAccount>();
      
        public final List<PaymentAccount> getPaymentAccounts() {
          return Utils.createSortedList(paymentAccounts);
        }
      
        public final void setPaymentAccounts(final List<PaymentAccount> paymentAccounts) {
          for (final PaymentAccount paymentAccount : new ArrayList<PaymentAccount>(this.paymentAccounts)) {
            removePaymentAccount(paymentAccount);
          }
      
          for (final PaymentAccount paymentAccount : paymentAccounts) {
            addPaymentAccount(paymentAccount);
          }
        }
      
        public final void addPaymentAccount(final PaymentAccount account) {
          account.addMobilePhone(this);
          paymentAccounts.add(account);
        }
      
        public final void removePaymentAccount(final PaymentAccount account) {
          paymentAccounts.remove(account);
          account.removeMobilePhone(this);
        }
      ...}



      @Entity
      public abstract class PaymentAccount ... {
        @ManyToMany
        private final List<MobilePhone> mobilePhones = new ArrayList<MobilePhone>();
      
        public final List<MobilePhone> getMobilePhones() {
          return Utils.createSortedList(mobilePhones);
        }
      
        final void addMobilePhone(final MobilePhone mobilePhone) {
          mobilePhones.add(mobilePhone);
        }
      
        final void removeMobilePhone(final MobilePhone mobilePhone) {
          mobilePhones.remove(mobilePhone);
        }
      ...}



      We use a RF picklist to add or remove entries on the edit page of the MobilePhone entity:


      <s:decorate template="/layout/edit.xhtml">
                    <rich:pickList id="paymentAccounts"
                      value="#{editMobileForm.instance.paymentAccounts}"
                      copyAllControlLabel="#{messages['general.addAll']}" 
                      copyControlLabel="#{messages['general.add']}" 
                      removeAllControlLabel="#{messages['general.removeAll']}"
                      removeControlLabel="#{messages['general.remove']}">
                      <s:selectItems value="#{editMobileForm.availablePaymentAccounts}" var="account" label="#{account.label}"/>
                      <s:convertEntity />
                    </rich:pickList>
                  </s:decorate>



      So this is the scenario:


      One user send requests to our system. They are invalid, if there is no association between the phone and the account.


      Another user meanwhile edits the mobile phone (it is read from the DB with entityManager.find())
      and removes the association using the pick list. He then presses Save which merely forwards him to another page.


      The first user however still sees stale data where the association still exists in the DB. The request should fail but doesn't.


      We switched on Hibernate's logging and viewed the created SQL statements. We noticed that the UPDATE and DELETE statement are not executed immediately after the page is left, but after some time later or when the user hits another page. (Which performs a query and thus flushes Hibernate's session).


      Only if we add a ((Session)entityManager.getDelegate()).isDirty() or a entityManager.flush() to the code of the Save-Action the data is immediately written to the DB as expected.


      Have you any clue, why the data is not written immediately in all cases? We had the suspicion that this might be somehow related to the relatively new pickList widget or the way we update the association list. We could not prove that, however.


      Thanks in advance for your help


         Markus