클래스 구현하기



public class MonetaryAmountCompositeUserType implements CompositeUserType {

public String[] getPropertyNames() {
return new String[] { “amount”, “currency” };
}

public Type[] getPropertyTypes() {
return new Type[] { Hibernate.BIG_DECIMAL, Hibernate.CURRENCY };
}

public Object getPropertyValue(Object component, int property)
throws HibernateException {
MonetaryAmount monetaryAmount = (MonetaryAmount) component;
if (property == 0)
return monetaryAmount.getAmount();
else
return monetaryAmount.getCurrency();
}

public Object nullSafeGet(ResultSet resultSet, String[] names,
SessionImplementor session, Object owner)
throws HibernateException, SQLException {
BigDecimal value = resultSet.getBigDecimal(names[0]);
if (resultSet.wasNull())
return null;
Currency currency = Currency.getInstance(resultSet.getString(names[1]));
return new MonetaryAmount(value, currency);
}

public void nullSafeSet(PreparedStatement statement, Object value,
int index, SessionImplementor arg3) throws HibernateException,
SQLException {
if (value == null) {
statement.setNull(index, Hibernate.BIG_DECIMAL.sqlType());
statement.setNull(index + 1, Hibernate.CURRENCY.sqlType());
} else {
MonetaryAmount amount = (MonetaryAmount) value;
String currencyCode = amount.getCurrency().getCurrencyCode();
statement.setBigDecimal(index, amount.getAmount());
statement.setString(index + 1, currencyCode);
}
}

public void setPropertyValue(Object arg0, int arg1, Object arg2)
throws HibernateException {
throw new UnsupportedOperationException(“Immutable MonetaryAmount!”);
}

}



  • CompositeUserType 인터페이스를 구현한다.


  • nullSafeSet()은 ResultSet에 담겨있는 두 개의 값을 Monetary 객체의 속성값으로 변환하면 된다.


  • nullSafeSet()은 객체가 가진 두 개의 값을 DB에 저장하도록 statement를 수정한다.


  • getPropertyNames()를 사용해서 Value Type의 속성들을 알려준다.


  • getPropertyValue()를 사용해서 Value Type의 각각의 속성이 가진 값을 알려준다.


  • setPropertyValue()를 사용해서 Value Type의 속성에 값을 설정한다.

맵핑하기



@org.hibernate.annotations.Type(
type = “persistence.MonetaryAmountUserType”
)
@org.hibernate.annotations.Columns(columns = {
@Column(name=“INITIAL_PRICE”),
@Column(name=“INITIAL_PRICE_CURRENCY”, length = 2)
})
private MonetaryAmount initialPrice;


  • 다음과 같이 쿼리를 작성할 수 있다.


from Item i
where i.initialPrice.amount > 100.0
and i.initialPrice.currency = ‘AUD’