-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Multiple Money objects with same currency–find() vs merge(
PostPosted: Fri Nov 17, 2006 2:00 pm 
Newbie

Joined: Sun Jun 18, 2006 10:55 pm
Posts: 1
Location: Los Angeles
Hibernate Core: 3.2.0 CR2
Hibernate Entity Manager: 3.2.0 CR1
Hibernate Annotations: 3.2.0 CR1
Database: Oracle 10g

Our project has multiple currencies. We have Money object which has attributes amount and currency (similar to the example in CaveatEmptor’s MonetaryAmount.java). However, we do not want to store currency in each table corresponding to each money attribute. We would like to have a subgraph of entities with Money objects in various entities but the currency is stored in only one entity of the subgraph. For e.g. some of the entities of the subgraph are ServiceCharge (root object of subgraph), ServiceChargeLine, ServiceChargeContextEventLine, ServiceChargeContextAgencyLine. These entities are connected (traversable with bidirectional relationship). Some of these entities have multiple Money objects. The corresponding database tables have amount part of the money. But the currency of Money objects of these entities is present in ServiceCharge (one entity of sub graph) only.

When we retrieve (from database) any entity that has Money object as attribute, we get the amount from the corresponding table, but the currency has to be retrieved by traversing object graph to the object that has currency. While persisting an entity that has Money attribute, the currency part of Money is not persisted in database.

We have an Interface CurrencyRetrieval which is implemented by each entity with Money attribute(s). This interface has a methods such as getCurrency(). This method traverses the object graph to retrieve the currency.

The custom UserType class MoneyType cannot be used to create Money objects with correct currency as the ‘owner’ object parameter of nullsafeget() method is not hydrated by the time it is called. So we cannot traverse the object graph to get the currency.

I tried to use EJB 3.0 PostLoad event callback method to retrieve the currency and set it in all money attributes of an entity. This approach works while retrieving the entities (using EntityManager’ find(class, PrimiaryKey)). However, it does not work when we update the entity graph using EntityManager.merge(entity). It seems when we call merge(), Hibernate is loading ServiceChargeLine first and calling PostLoad call back method before hydrating its parent object ServiceCharge.

Questions:
1) Why is the PostLoad method/hydration working fine when we call EntityManager.find(), but not working when we call EntityManager.merge()?
2) How can we make it work in both find() and merge()?
3) Please suggest any other suggestions/ideas to retrieve Currency part of Money from another entity?

Any suggestions, code samples are greatly appreciated.

Simplified code I am using is:

Code:
public interface CurrencyRetrieval {
   public String getCurrencyCode();
   public void setCurrencyInMoneyObjects();
}


@Entity
@Table(name="SERVICE_CHARGE_LINE")
public class ServiceChargeLine implements CurrencyRetrieval{

   @Id @Column(name = "SERVICE_CHARGE_LINE_ID")
   @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SERVICE_CHARGE_LINE_ID_GEN")
   private Long id;

    @ManyToOne(targetEntity = ServiceCharge.class, optional=false, fetch = FetchType.EAGER)
    @JoinColumn(name="SERVICE_CHARGE_ID")
   private ServiceCharge serviceCharge;

   @Column(name="CHARGEABLE_AMOUNT", columnDefinition = "NUMBER(22,5)", nullable = true)
   @Type(type = "MoneyType")
   private Money changeableAmount;

   /* Traverse the object graph to retrieve the Currency code
   // THIS IS GIVING CURRENCY CODE AS NULL, IF WE CALL ENTITYMANAGER's MERGE().
   // THE ATTRIBUTES OF PARENT OBJECT 'SERVICECHARGE' ARE NOT HYDRATED EXCEPT THE PRIMARY KEY.
   // THE HYDRATION OF PARENT IS DONE WHEN WE CALL ENTITYMANAGER.FIND() IS CALLED.
*/
   public String getCurrencyCode(){
      return serviceCharge.getCurrencyCode();
   }

   // Sets the currency in Money attributes of this entity
   public void setCurrencyInMoneyObjects(){
      String currencyCode = getCurrencyCode();

      Money.setCurrency(changeableAmount, currencyCode);
   }
}


// Entity having currency code.
@Entity
@Table(name="SERVICE_CHARGE")
public class ServiceCharge {

   @Id @Column(name = "SERVICE_CHARGE_ID")
   @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SERVICE_CHARGE_ID_GEN")
   private Long id;

   @Column(name = "CURRENCY_CODE", length = 3, nullable = false)
   private String currencyCode;

   @OneToMany(targetEntity = ServiceChargeLine.class, mappedBy = "serviceCharge", cascade = CascadeType.ALL)
   @JoinColumn(name = "SERVICE_CHARGE_ID", nullable = false)
   private Collection<ServiceChargeLine> serviceChargeLines;

}


Thanks,
Srinivas


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.