4

我有一个带有EmebeddedId. 实体上的实体侦听器(在加载时修剪空白Strings)正在按预期Embeddable触发,根本不会触发 id 上的相同侦听器。

我做错了吗?如何修复?

实体:

@Entity
@Table(name = "SUBMITTER_VIEW")
@EntityListeners(TrimListener.class)
public class Submitter implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private SubmitterPK id;

    @Trim
    @Column(name = "DOC_NAME")
    private String name;
...

可嵌入:

@Embeddable
@EntityListeners(TrimListener.class)
public class SubmitterPK implements Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name = "LSTORT")
    private String bsnr;

    @Trim
    @Column(name = "LOGIN")
    private String login;
...

听众:

public class TrimListener {

    Logger log = LoggerFactory.getLogger("TrimListener");

    @PostLoad
    public void repairAfterLoad(final Object entity) throws IllegalAccessException {

        log.debug("trimlistener active");

        final Set<Field> trimProps = getTrimProperties(entity.getClass());

        for (final Field fieldToTrim : trimProps) {
            final String propertyValue = (String) fieldToTrim.get(entity);
            if (propertyValue != null) {
                fieldToTrim.set(entity, propertyValue.trim());
            }
        }
    }
...
4

2 回答 2

3

我认为它显然被忽略了,因为它不是 JPA 2.0 所期望的标准位置。根据 JPA 2.0 最终规范,实体侦听器可以是实体、映射的超类或其中之一关联的侦听器(请参阅规范的第 3.5 节):

可以将方法指定为生命周期回调方法以接收实体生命周期事件的通知。可以在实体类、映射超类或与实体或映射超类关联的实体侦听器类上定义生命周期回调方法

于 2012-11-15T13:28:57.160 回答
2

我已经调整了 EntityListener 以递归地跟踪使用Embeddable. 现在,如果一个实体使用监听器,所有嵌入的类也会被处理:

public class TrimListener {

    @PostLoad
    public void trimAfterLoad(final Object entity) throws IllegalAccessException {

        final Set<Trimmable> trimProps = getTrimProperties(entity);

        for (final Trimmable trimmable : trimProps) {
            final String propertyValue = (String) trimmable.field.get(trimmable.target);
            if (propertyValue != null) {
                trimmable.field.set(trimmable.target, propertyValue.trim());
            }
        }
    }

    private Set<Trimmable> getTrimProperties(final Object entity) throws IllegalAccessException {

        final Class<?> entityClass = entity.getClass();
        final Set<Trimmable> propertiesToTrim = new HashSet<Trimmable>();

        for (final Field field : entityClass.getDeclaredFields()) {
            if (field.getType().equals(String.class) && (field.getAnnotation(Trim.class) != null)) {
                field.setAccessible(true);
                propertiesToTrim.add(new Trimmable(entity, field));
                // if the entity contains embeddables, propagate the trimming
            } else if (field.getType().getAnnotation(Embeddable.class) != null) {
                field.setAccessible(true);
                propertiesToTrim.addAll(getTrimProperties(field.get(entity)));
            }
        }
        return propertiesToTrim;
    }

    private class Trimmable {

        final Object target;
        final Field field;

        public Trimmable(final Object target, final Field field) {
            this.target = target;
            this.field = field;
        }
    }
}
于 2012-11-15T15:16:47.303 回答