Expand my Community achievements bar.

Learn about Edge Delivery Services in upcoming GEM session

Many-to-one synchronization

Avatar

Level 1

I'm using DataServices to manage hiberate objects.  I have a simple many-to-one relationship between Account and Transaction (an account has many transactions).  I have two DataGrids in my application, one display accounts and their balances(which are derived from the trasactions, there is no balance field) the other displays transactions.  When I edit the accounts, the changes are propogated to the child transactions.  However, when I edit the transactions, the changes are not propagated to the accounts automatically.  If I edit the account or resort the columns it will update the balance.  My data-management-config.xml is below.  My question is, is there a way to make this work or is this not working by design?  I want my Account objects to automatically get the new Transactions associated with them so the balance will update correctly.

<destination id="AccountHibernate">
     <adapter ref="java-dao" />
     <properties>
          <use-transactions>true</use-transactions>
          <source>flex.data.assemblers.HibernateAssembler</source>
          <scope>application</scope>
          <metadata>
               <identity property="accountId"/>
               <one-to-many property="transactions" destination="TransactionHibernate" lazy="false" read-only="true" load-on-demand="true"/>  
          </metadata>
          <network>
               <session-timeout>0</session-timeout>
          </network>
          <server>
               <hibernate-entity>budget.data.Account</hibernate-entity>
               <fill-method>
                    <name>fill</name>
                    <params>java.util.List</params>
               </fill-method>
               <fill-configuration>
                    <use-query-cache>false</use-query-cache>
                    <allow-hql-queries>true</allow-hql-queries>
               </fill-configuration>
          </server>
     </properties>
</destination>

<destination id="TransactionHibernate">
          <adapter ref="java-dao" />
          <properties>
               <use-transactions>true</use-transactions>
               <source>flex.data.assemblers.HibernateAssembler</source>
               <scope>application</scope>
               <metadata>
                    <identity property="transactionId"/>
                    <many-to-one property="account"  destination="AccountHibernate" lazy="false" />
               </metadata>
          <network>
               <session-timeout>0</session-timeout>
          </network>
          <server>
               <hibernate-entity>budget.data.Transaction</hibernate-entity>
               <fill-method>
                    <name>fill</name>
                    <params>java.util.List</params>
               </fill-method>
               <fill-configuration>
                    <use-query-cache>false</use-query-cache>
                    <allow-hql-queries>true</allow-hql-queries>
               </fill-configuration>
          </server>
     </properties>
</destination>

4 Replies

Avatar

Level 1

Hi jmnas,

When you say "edit accounts" and "edit transactions", are you editing attributes of those objects or are you modifying relationships between them, i.e. changing the account associated with a transaction?

Also, it sounds like the problematic case is, you assign a new transaction to an account but the balance total for that account does not get automatically updated.  Can you please verify that the collection field of the appropriate account is not getting updated?  It is possible that the account's transaction collection is being updated correctly but there is no binding to trigger a recalculation of the balance based on that update. 

Thanks,

Ed

Avatar

Level 1

Ed: Thanks for your response, I think I have a better idea of what is going

on now.

Regarding the first question: In this case I am just modifying an attribute,

the relationship between them remains the same.

I verified that adding a transaction does not update the size of the

transaction collection the account has if I add the new transaction to the

transactions collection. However, if I add the transaction to the

appropriate accounts list of transactions it does update the collection

(i.e. there is one more element) but it does not update the balance. I have

since changed my balance to a property that is calculated by a query server

side. I noticed that even if I change a property on the account, it will

not update the balance unless I call fill again.

So I have two questions: 1) is there a way to make the account realize it

has transactions added to it without adding them directly to the account's

transaction collection? 2) Is there a way to force the account object to

refresh the balance (i.e. re-run the query to generate it?). I realize I

can call fill() again client side and easily fix this, but I would like to

do this in a way that causes all clients to have their account balances

refreshed when the should i.e. I want the server to automatically push the

new balance property. If it matters I'm using HibernateAssembler. Could I

extend that to achieve this?

Jim

Avatar

Employee

There is a hierarchical-events setting which may able to solve your problem. As what you  found in Ed's response, the account only has property change event when there is membership change of transactions.  If your account balance is derived property which calculate the sum of the transaction. The bubble up property change event should work.  If your account sum amount is calculated on the server side(trigger, stored procedure update....),  you can use the DataTransaction to push the update message to the destinated account.   You can also modify the transactions setter to add account as property change event listener to each transaction. When there is a change event, you can either call the getItem or recalculate your balance

<many-to-one destination="Account"  property="account" hierarchical-events="true"/>

William C

Avatar

Level 1

Thanks guys I have both issues resolved. For anyone that finds this later:

In one case LCDS was sending the changes to the client, I have had to add a

listener to the object in my custom renderer. In the case of account

balances (which are calculated with a query server side) I had to add a

listener on my managed transaction ArrayCollection to call

refreshCollections on the managed account ArrayCollection. I think

hierarchial-events would have worked but it might have also caused a large

chain of updates in my case.