클래스 구현하기



public class MonetaryAmountUserType implements UserType {

public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}

public Object deepCopy(Object value) throws HibernateException {
return value;
}

public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}

public boolean equals(Object x, Object y) throws HibernateException {
if (x == y)
return true;
if (x == null || y == null)
return false;
return x.equals(y);
}

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

public boolean isMutable() {
return false;
}

public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner)
throws HibernateException, SQLException {

BigDecimal valueInUSD = resultSet.getBigDecimal(names[0]);
if (resultSet.wasNull())
return null;

// DB에서 가져온 다음에 원하는 값으로 캐스팅 해서 반환.

return null;
}

public void nullSafeSet(PreparedStatement statement, Object value, int index)
throws HibernateException, SQLException {

// SQL을 DB에 보내기 전에 statement의 특정 위치에 들어갈 값을 변경한다.

}

public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return original;
}

public Class returnedClass() {
return MonetaryAmount.class;
}

public int[] sqlTypes() {
return new int[] { Hibernate.BIG_DECIMAL.sqlType() };
}

}



  • sqlTypes() 메소드는 하이버네이트가 어떤 SQL 컬럼 타입으로 DDL 스키마를 생성할 지 알려준다.


  • returnClass() 메소드는 어떤 자바 타입을 맵핑할 것인지 알려준다.


  • deepCopy()는 스냅샷 객체을 전달해 준다. 따라서, immutable한 타입일 경우에는 그냥 넘기면 된다.


  • disassemble()은 MonetaryAmount를 하이버네이트 2차 캐쉬에 집어 넣을 때 호출된다. 이곳에서 직렬화된 상태로 데이터를 캐슁한다.


  • assemble()은 캐쉬된 상태의 데이터를 MonetaryAmount 객체로 변환한다.


  • replace()는 detached 상태의 객체를 merging할 때 사용한다.


  • equals()는 dirty checking 할 때 사용한다.


  • nullSafeGet()은 ResultSet에서 데이터를 가져올 때 사용한다.


  • nullSafeSet()은 PreparedStatement에 저장할 값을 설정할 때 사용한다.

맵핑하기



@org.hibernate.annotations.Type(
type = ” persistence.MonetaryAmountUserType”
)
@Column(name = “INITIAL_PRICE”)
private MonetaryAmount initialPrice;

단점



  • 하이버네이트는 Monetary Amount의 속성을 모른다. 따라서 그 안에 있는 amount나 currency를 가져오는 쿼리를 작성할 수 없다.

해결책



  • CompositeUserType을 사용하면 된다.
<!–

–>