Hibernate _ note 33 (create CompositeUserType and parameterized customization type)

Source: Internet
Author: User

Create CompositeUserType

Public class MonetaryAmountCompositeUserType implements CompositeUserType {@ SuppressWarnings ("unchecked") public Class returnedClass () {return MonetaryAmount. class;} public boolean isMutable () {return false;} // snapshot of the created value public Object deepCopy (Object value) throws HibernateException {return value ;} // cache for storing information in serialized form public Serializable disassemble (Object value, SessionImplementor session) throws HibernateExc Eption {return (Serializable) value;} // convert the cached data to a public Object assemble (Serializable cached, SessionImplementor session, Object owner) instance of MonetaryAmount) throws HibernateException {return cached;} // process the merged public Object replace (Object original, Object target, SessionImplementor session, Object owner) throws HibernateException {return original ;} public boolean equals (Object x, Object y) throws Hiber NateException {if (x = y) return true; if (null = x | null = y) return false; return x. equals (y);} public int hashCode (Object x) throws HibernateException {return x. hashCode ();} // obtain the attribute value from the JDBC ResultSet public Object nullSafeGet (ResultSet rs, String [] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {BigDecimal value = rs. getBigDecimal (names [0]); if (rs. wasNull () re Turn null; Currency currency = Currency. getInstance (rs. getString (names [1]); return new MonetaryAmount (value, currency);} // write the attribute value to the PreparedStatementpublic void nullSafeSet (PreparedStatement st, Object value, int index, sessionImplementor session) throws HibernateException, SQLException {if (null = value) {st. setNull (index, BigDecimalType. INSTANCE. sqlType (); st. setNull (index + 1, CurrencyType. INSTANCE. SqlType ();} else {MonetaryAmount amount = (MonetaryAmount) value; String currencyCode = amount. getCurrency (). getCurrencyCode (); st. setBigDecimal (index, amount. getAmount (); st. setString (index + 1, currencyCode) ;}// public value type attribute public String [] getPropertyNames () {return new String [] {"amount ", "currency" };}// attribute Type public Type [] getPropertyTypes () {return new Type [] {BigDecimalType. INSTANCE, CurrencyType. INSTANCE} ;} // Return MonetaryAmount's single attribute value public Object getPropertyValue (Object component, int property) throws HibernateException {MonetaryAmount monetaryAmount = (MonetaryAmount) component; if (property = 0) {return monetaryAmount. getAmount ();} else {return monetaryAmount. getCurrency () ;}} public void setPropertyValue (Object component, int property, Object value) throws HibernateException {throw new UnsupportedOperatio NException ("Immutable MonetaryAmount! ");}}
The initialPrice attribute is now mapped to two columns. Therefore, you must declare both columns in the ing file. The first column stores the value; the second column stores the currency type of MonetaryAmount:
     
      
  
 
If you map items through annotations, you must declare several columns for this attribute. The javax. persistence. Column annotation cannot be used multiple times. Therefore, a new annotation specific to Hibernate is required:
@org.hibernate.annotations.Type(    type = "persistence.MonetaryAmountUserType")@org.hibernate.annotations.Columns(columns = {    @Column(name = "INITIAL_PRICE"),    @cOLUMN(NAME = "INITIAL_PRICE_CURRENCY", length = 2)})
In Hibernate queries, you can now reference custom types of amount and currency attributes, even if they do not appear as individual attributes anywhere in the ing file:
from Item iwhere i.initialPrice.amount > 100.0    and i.initiaPrice.currency = 'AUD'
Parameterized custom types assume that you once again face the initial problem: when you save the amount to the database, convert it into a different currency type. These problems are often more subtle than general conversions; for example, you can save the dollar in some tables, while saving the euro in other tables. You still want to write a single custom ing type for it so that it can be converted at will. It is possible to add the ParameterizedType interface to the UserType or CompositeUserType class:
Public class MonetaryAmountConversionType implements UserType, ParameterizedType {private Currency convertize; public void setParameterValues (Properties parameters) {this. convertion = Currency. getInstance (parameters. getProperty ("convertize");} public int [] sqlTypes () {return new int [] {BigDecimalType. INSTANCE. sqlType (), StringType. INSTANCE. sqlType () };}@ SuppressWarnings ("unchecked") public Class returnedClass () {return MonetaryAmount. class;} public boolean isMutable () {return false;} // snapshot of the created value public Object deepCopy (Object value) throws HibernateException {return value ;} // cache for storing information in serialized form public Serializable disassemble (Object value, SessionImplementor session) throws HibernateException {return (Serializable) value ;} // convert the cached data to an instance of MonetaryAmount public Serializable disassemble (Object value) throws HibernateException {return (Serializable) value;} public Object assemble (Serializable cached, Object owner) throws HibernateException {return cached;} // merge public Object replace (Object original, Object target, Object owner) to process the status of the unmanaged Object throws HibernateException {return original ;} public boolean equals (Object x, Object y) throws HibernateException {if (x = y) return true; if (null = x | null = y) return false; return x. equals (y);} public int hashCode (Object x) throws HibernateException {return x. hashCode ();} public Object nullSafeGet (ResultSet rs, String [] names, Object owner) throws HibernateException, SQLException {BigDecimal value = rs. getBigDecimal (names [0]); if (rs. wasNull () return null; Currency currency = Currency. getInstance (rs. getString (names [1]); return new MonetaryAmount (value, currency);} public void nullSafeSet (PreparedStatement st, Object value, int index) throws HibernateException, SQLException {if (null = value) {st. setNull (index, BigDecimalType. INSTANCE. sqlType (); st. setNull (index + 1, CurrencyType. INSTANCE. sqlType ();} else {MonetaryAmount amount = (MonetaryAmount) value; st. setBigDecimal (index, amount. convert (convertize); st. setString (index + 1, amount. getCurrency (). getCurrencyCode ());}}}
When customizing the ing type for an application, you must set the configuration parameters in the ing file. A simple solution is embedded in attributes. Ing:
      
       
       
           
    USD    
   
  
However, if you have many currency amounts in your domain model, this is inconvenient and requires replication. A better policy is to use a single definition of the type, including all parameters, with a unique name that can be reused in all mappings. Through a single Element (you can also use it without passing the parameter) to complete this proportion:
       
    USD
   
       
    EUR
   
The following describes how to bind custom ing types with some parameters to the names monetary_amount_usd and monetary_amount_eur. This definition can be placed anywhere in the ing file; it is . With the Hibernate extension, you can define a custom type with parameters in the annotation:
@org.hibernate.annotations.TypeDefs({@org.hibernate.annotations.TypeDef(name = "monetary_amount_usd",typeClass = persistence.MonetaryAmountConversionType.class,parameters = {@Parameter(name = "convertTo", value = "USD")}),@org.hibernate.annotations.TypeDef(name = "monetary_amount_eur",typeClass = persistence.MonetaryAmountConversionType.class,parameters = {@Parameter(name = "convertTo", value = "EUR")})})
This annotation metadata is also global, so it can be placed out of any Java class Declaration or in a separate file package-info.java.
In the XML ing file and annotation ing, the name of the defined type is referenced, instead of the class name that is fully qualified for the custom type:
        
         
     
    
@org.hibernate.annotations.Type(type = "monetary_amount_eur")@org.hibernate.annotations.Columns({    @Column(name = "BID_AMOUNT"),    @Column(name = "BID_AMOUNT_CUR")})private MonetaryAmount bidAmount;

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.