두가지의 방법이 있다. 첫번째는 JBoss-Hibernate에서 제공되는 @ColumnTransformer를 사용하는 방법과 Listener를 적용하는 방법.
DB에 종속적인 모델이지만, 개인적으로는 첫번째 방법인 ColumnTransformer를 추천한다.
ColumnTransformer를 적용하는 방법.
..
@ColumnTransformer(write="trim(?)")
@Column(name = "title", nullable = false)
private String title;
..
TrimListener를 만들어 적용하는 방법
@Trim Annotaion을 지정한다고 보면, Annotaion의 적용 대상은 method나 field일 것이다. 그러니 @interface의 적용 대상을 field, method로 지정한다.
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { FIELD, METHOD, ANNOTATION_TYPE })
public @interface Trim {
}
적용 대상이 EntityListeners이므로 이름을 TrimListener로 지정하고 작성해 보자.
1. @Trim Annotaion이 있는 필드를 찾아서 반환하는 메스드를 먼저 만들어 둔다.
public class TrimListener {
private final Map<Class<?>, Set<Field>> trimFieldMap = new HashMap<Class<?>, Set<Field>>();
private Set<Field> getTrimAnnotationFields(Class<?> entity) throws Exception {
Set<Field> trimFields = trimFieldMap.get(entity);
if (trimFields == null) {
trimFields = new HashSet<Field>();
Field[] fields = entity.getDeclaredFields();
for (Field field : fields) {
if (field.getType().equals(String.class) && field.getAnnotation(Trim.class) != null) {
field.setAccessible(true);
trimFields.add(field);
}
}
trimFieldMap.put(entity, trimFields);
}
return trimFields;
}
2. 1에서 반환한 Trim Annotaion의 목록 field를 실제 trim처리하는 메소드를 만든다. Listener이므로 @PostLoad에서 처리하도록 한다.
@PostLoad
public void replacePostLoad(final Object entity) throws Exception {
Set<Field> trimFields = getTrimAnnotationFields(entity.getClass());
for (Field trimField : trimFields) {
String trimFieldValue = (String) trimField.get(entity);
if (!StringUtils.isEmpty(trimFieldValue)) {
trimField.set(entity, trimFieldValue.trim());
}
}
}
3. 적용할 클래스 field에 @Trim을 적용을 하고, EntityListener에 등록하자.
@Data
@NoArgsConstructor
@EntityListeners(value = { AuditingEntityListener.class, TrimListener.class })
@Entity(name = "Faq")
@Table(name = "faq")
public class Faq implements Autocompletable<Faq> {
...
@Trim
@Column(name = "title", nullable = false)
private String title;
...
그냥 TRIM 함수 사용하기
@Modifying
@Query("update XxxEntity o set o.name = TRIM(:name) where o.id = :id")
void updateOptGoodsCd(@Param("id") Long id, @Param("name") String name);
실제 테스트를 돌려보면 find/save시에 trim이 적용된 것을 볼 수 있다.