-->
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: How to use CompositeUSerType
PostPosted: Mon Sep 03, 2012 7:44 am 
Newbie

Joined: Mon Sep 03, 2012 7:17 am
Posts: 1
I am using Hibernate 4.0. I have create CompositeUserType as following

Code:
public class MoneyType implements CompositeUserType {
    @Override
    public String[] getPropertyNames() {
        // ORDER IS IMPORTANT!  it must match the order the columns are defined in the property mapping
        return new String[] { "amount", "currency" };
    }

    @Override
    public Type[] getPropertyTypes() {
        return new Type[] { StringType.INSTANCE, StringType.INSTANCE };
    }

    public Class getReturnedClass() {
        return Money.class;
    }

    @Override
    public Object getPropertyValue(Object component, int propertyIndex) {
        if ( component == null ) {
            return null;
        }

        final Money money = (Money) component;
        switch ( propertyIndex ) {
        case 0: {
            return money.getAmount();
        }
        case 1: {
            return money.getCurrency();
        }
        default: {
            throw new HibernateException( "Invalid property index [" + propertyIndex + "]" );
        }
        }
    }

    @Override
    public void setPropertyValue(Object component, int propertyIndex, Object value) throws HibernateException {
        throw new UnsupportedOperationException("Immutable!");
    }

    @SuppressWarnings("unused")
    @Override
    public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws SQLException {
        assert names.length == 2;
        BigDecimal amount = new BigDecimal(decrypt((String)StringType.INSTANCE.get(rs, names[0], session)));
        Currency currency = Currency.getInstance(decrypt((String)StringType.INSTANCE.get( rs, names[1], session)));
        if(amount==null && currency == null)
        {
            return null;
        }
        else if(amount == null)
        {
            return new Money(currency);
        }
        return new Money(amount);
    }

    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws SQLException {
        if ( value == null ) {
            StringType.INSTANCE.set( st, null, index, session );
            StringType.INSTANCE.set( st, null, index+1, session );
        }
        else {
            final Money money = (Money) value;
            StringType.INSTANCE.set( st, encrypt(money.getAmount()), index, session );
            StringType.INSTANCE.set( st, encrypt(money.getCurrency()), index+1, session );
        }
    }

    private String encrypt(Object data)
    {
        return data.toString();
    }

    private String decrypt(String data)
    {
        return data;
    }

    @Override
    public Class returnedClass()
    {
        return Money.class;
    }

    @Override
    public boolean equals(Object x, Object y) throws HibernateException
    {
        return x.equals(y);
    }

    @Override
    public int hashCode(Object x) throws HibernateException
    {
        return x.hashCode();
    }

    @Override
    public Object deepCopy(Object value) throws HibernateException
    {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean isMutable()
    {
        return false;
    }

    @Override
    public Serializable disassemble(Object value, SessionImplementor session) throws HibernateException
    {
        return (Serializable) value;
    }

    @Override
    public Object assemble(Serializable cached, SessionImplementor session, Object owner) throws HibernateException
    {
        return cached;
    }

    @Override
    public Object replace(Object original, Object target, SessionImplementor session, Object owner) throws HibernateException
    {
        // TODO Auto-generated method stub
        return null;
    }
}


Then I want to use this MoneyType inside my Price class as follows
Code:
@Entity
@Table(name = "price")
@TypeDef(name = "moneyType", typeClass = MoneyType.class)
public class Price
{
    private Money money;

    /**
     * @return The money.
     */
    @Embedded
    @Type(type="moneyType")
    @Columns(columns = { @Column(name = "amount"),
            @Column(name = "currency")})
    public Money getMoney()
    {
        return money;
    }

    /**
     * @param money The money to set.
     */
    public void setMoney(Money money)
    {
        this.money = money;
    }
}

And Money class looks as follows
Code:
@Embeddable
public final class Money implements Cloneable, Comparable<Money>, Serializable
{
    private final Currency           currency;
    private final BigDecimal         amount;

    public Money()
    {
        this(BigDecimal.ZERO);
    }
    /**
     * Sets the amount for this instance. The currency is set to the currency
     * assigned to default system locale.
     *
     * @param amount A {@link BigDecimal}.
     */
    public Money(final BigDecimal amount)
    {
        this(Currency.getInstance(Locale.getDefault()), amount);
    }

    /**
     * Sets the amount for this instance. The currency is set to the currency
     * assigned to default system locale.
     *
     * @param amount A {@link BigInteger}.
     */
    public Money(final BigInteger amount)
    {
        this(new BigDecimal(amount));
    }

    /**
     * Sets the currency for this instance. The amount is set to zero.
     *
     * @param currency A {@link Currency}.
     */
    public Money(final Currency currency)
    {
        this(currency, BigDecimal.ZERO);
    }
    /**
     * Sets the currency and amount for this instance.
     *
     * @param currency A {@link Currency}.
     * @param amount A {@link BigDecimal}.
     */
    public Money(final Currency currency, final BigDecimal amount)
    {
        if (currency == null)
        {
            throw new RuntimeException("Currency cannot be null.");
        }

        if (amount == null)
        {
            throw new RuntimeException("Amount cannot be null.");
        }

        this.currency = currency;
        this.amount = amount.setScale(currency.getDefaultFractionDigits(), ROUNDING_MODE);
    }

    /**
     * Gets the amount for this instance.
     *
     * @return The amount for this instance.
     */
    public BigDecimal getAmount()
    {
        return this.amount.abs();
    }

    /**
     * Gets the currency for this instance.
     *
     * @return The currency for this instance.
     */
    public Currency getCurrency()
    {
        return this.currency;
    }
}


In this case I found that even after defining

@TypeDef(name = "moneyType", typeClass = MoneyType.class)
And

@Embedded
@Type(type="moneyType")
@Columns(columns = { @Column(name = "amount"),
@Column(name = "currency")})
public Money getMoney()
{
return money;
}


Money in my case is not getting persisted as per my defined CompositeUserType MoneyType. I never get control in MoneyType whenever I try to save/retrieve Price.
I found that MoneyType is not getting applied on money in Price class.


Am I missing anything here? Is there anyother configuration here which I am missing?


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.