본문 바로가기

개발

하이버네이트 커스텀 벨류 타입 - 3

반응형

이번 포스팅에서는 어떻게 커스텀하는지에 대해 알아보겠습니다

 

아래와 같은 3단계 과정을 거쳐 진행하겠습니다

1. 우선 하이버네이트의 Type을 상속받은 커스텀 타입객체를 하나 제작합니다

2. 해당 타입 객체에서 사용할 Descriptor 객체도 하나 제작합니다

3. 이렇게 제작한 Type을 등록해줍니다

 

public class AgeType extends AbstractSingleColumnStandardBasicType<Age> implements DiscriminatorType<Age> {
    public static final AgeType INSTANCE = new AgeType();
    public AgeType() {
        super(IntegerTypeDescriptor.INSTANCE, AgeTypeDescriptor.INSTANCE);
    }

    @Override
    public String getName() {
        return "age";
    }

    @Override
    public Age stringToObject(String value) throws Exception {
        return fromString(value);
    }

    @Override
    public String objectToSQLString(Age age, Dialect dialect) throws Exception {
        return toString(age);
    }
}

위와 같이 타입 객체를 제작합니다

 

public class AgeTypeDescriptor extends AbstractTypeDescriptor<Age> {
    public static final AgeTypeDescriptor INSTANCE = new AgeTypeDescriptor();

    protected AgeTypeDescriptor() {
        super(Age.class);
    }

    @Override
    public Age fromString(String s) {
        if (s.isEmpty()) return null;
        int val =  Integer.parseInt(s);
        return new Age(val);
    }

    @Override
    public <X> X unwrap(Age age, Class<X> type, WrapperOptions wrapperOptions) {
        if (age == null) return null;
        if (Age.class.isAssignableFrom(type)) {
            return (X) age;
        }
        if (String.class.isAssignableFrom(type)) {
            return (X) toString(age);
        }
        if (Integer.class.isAssignableFrom(type)) {
            return (X) Integer.valueOf(age.getAge());
        }
        throw unknownUnwrap(type);
    }

    @Override
    public <X> Age wrap(X value, WrapperOptions wrapperOptions) {
        if (value == null) return null;
        if (String.class.isInstance(value)) {
            fromString((String) value);
        }
        if (Age.class.isInstance(value)) {
            return (Age) value;
        }
        if (Integer.class.isInstance(value)) {
            return new Age((Integer) value);
        }
        throw  unknownWrap(value.getClass());
    }
}

그리고 어떻게 wrap하고, unwrap할지에 대한 로직을 구현합니다

 

@TypeDef( name = "age", defaultForType = Age.class, typeClass = AgeType.class )

마지막으로 위처럼 엔티티에 어노테이션을 활용하여 타입을 등록해주면 됩니다!

 

 

모든 소스코드는 저의 레포지토리에서 확인 가능합니다

커밋: 6ed374d4eea54bd350fb1995fc80437344ad6aeb

반응형