Class JodaMoneyType

java.lang.Object
google.registry.persistence.converter.JodaMoneyType
All Implemented Interfaces:
org.hibernate.usertype.CompositeUserType

public class JodaMoneyType extends Object implements org.hibernate.usertype.CompositeUserType
Defines JPA mapping for Joda Money type.

Money is mapped to two table columns, a text currency column that stores the currency code, and a numeric amount column that stores the amount.

The main purpose of this class is to normalize the amount loaded from the database. To support all currency types, the scale of the numeric column is set to 2. As a result, the BigDecimal instances obtained from query ResultSets all have their scale at 2. However, some currency types, e.g., JPY requires that the scale be zero. This class strips trailing zeros from each loaded BigDecimal, then calls the appropriate factory method for Money, which will adjust the scale appropriately.

Although CompositeUserType is likely to suffer breaking change in Hibernate 6, it is the only option. The suggested alternatives such as Hibernate component or Java Embeddable do not work in this case. Hibernate component (our previous solution that is replaced by this class) does not allow manipulation of the loaded amount objects. Java Embeddable is not applicable since we do not own the Joda money classes.

Usage:


 '@'Type(type = JodaMoneyType.TYPE_NAME)
 '@'Columns(
   columns = {
     '@'Column(name = "cost_amount"),
     '@'Column(name = "cost_currency")
   }
 )
 Money cost;
 
  • Field Details

    • INSTANCE

      public static final JodaMoneyType INSTANCE
    • TYPE_NAME

      public static final String TYPE_NAME
      The name of this type registered with JPA. See the example in class doc.
      See Also:
  • Constructor Details

    • JodaMoneyType

      public JodaMoneyType()
  • Method Details

    • getPropertyNames

      public String[] getPropertyNames()
      Specified by:
      getPropertyNames in interface org.hibernate.usertype.CompositeUserType
    • getPropertyTypes

      public org.hibernate.type.Type[] getPropertyTypes()
      Specified by:
      getPropertyTypes in interface org.hibernate.usertype.CompositeUserType
    • getPropertyValue

      public Object getPropertyValue(Object component, int property) throws org.hibernate.HibernateException
      Specified by:
      getPropertyValue in interface org.hibernate.usertype.CompositeUserType
      Throws:
      org.hibernate.HibernateException
    • setPropertyValue

      public void setPropertyValue(Object component, int property, Object value) throws org.hibernate.HibernateException
      Specified by:
      setPropertyValue in interface org.hibernate.usertype.CompositeUserType
      Throws:
      org.hibernate.HibernateException
    • returnedClass

      public Class returnedClass()
      Specified by:
      returnedClass in interface org.hibernate.usertype.CompositeUserType
    • equals

      public boolean equals(Object x, Object y) throws org.hibernate.HibernateException
      Specified by:
      equals in interface org.hibernate.usertype.CompositeUserType
      Throws:
      org.hibernate.HibernateException
    • hashCode

      public int hashCode(Object x) throws org.hibernate.HibernateException
      Specified by:
      hashCode in interface org.hibernate.usertype.CompositeUserType
      Throws:
      org.hibernate.HibernateException
    • nullSafeGet

      @Nullable public Object nullSafeGet(ResultSet rs, String[] names, org.hibernate.engine.spi.SharedSessionContractImplementor session, Object owner) throws org.hibernate.HibernateException, SQLException
      Specified by:
      nullSafeGet in interface org.hibernate.usertype.CompositeUserType
      Throws:
      org.hibernate.HibernateException
      SQLException
    • nullSafeSet

      public void nullSafeSet(PreparedStatement st, Object value, int index, org.hibernate.engine.spi.SharedSessionContractImplementor session) throws org.hibernate.HibernateException, SQLException
      Specified by:
      nullSafeSet in interface org.hibernate.usertype.CompositeUserType
      Throws:
      org.hibernate.HibernateException
      SQLException
    • deepCopy

      public Object deepCopy(Object value) throws org.hibernate.HibernateException
      Specified by:
      deepCopy in interface org.hibernate.usertype.CompositeUserType
      Throws:
      org.hibernate.HibernateException
    • isMutable

      public boolean isMutable()
      Specified by:
      isMutable in interface org.hibernate.usertype.CompositeUserType
    • disassemble

      public Serializable disassemble(Object value, org.hibernate.engine.spi.SharedSessionContractImplementor session) throws org.hibernate.HibernateException
      Specified by:
      disassemble in interface org.hibernate.usertype.CompositeUserType
      Throws:
      org.hibernate.HibernateException
    • assemble

      public Object assemble(Serializable cached, org.hibernate.engine.spi.SharedSessionContractImplementor session, Object owner) throws org.hibernate.HibernateException
      Specified by:
      assemble in interface org.hibernate.usertype.CompositeUserType
      Throws:
      org.hibernate.HibernateException
    • replace

      public Object replace(Object original, Object target, org.hibernate.engine.spi.SharedSessionContractImplementor session, Object owner) throws org.hibernate.HibernateException
      Specified by:
      replace in interface org.hibernate.usertype.CompositeUserType
      Throws:
      org.hibernate.HibernateException