Java 如何在嵌入式系统上触发EntityListener

Java 如何在嵌入式系统上触发EntityListener,java,jakarta-ee,jpa,jpa-2.0,Java,Jakarta Ee,Jpa,Jpa 2.0,我有一个实体具有emebededId。实体上的实体侦听器(加载时修剪空白字符串)正在按预期触发,idEmbedded上的同一侦听器根本不会触发 我做错了吗?怎么能修好呢 实体: @Entity @Table(name = "SUBMITTER_VIEW") @EntityListeners(TrimListener.class) public class Submitter implements Serializable { private static final long seri

我有一个实体具有
emebededId
。实体上的实体侦听器(加载时修剪空白
字符串
)正在按预期触发,id
Embedded
上的同一侦听器根本不会触发

我做错了吗?怎么能修好呢

实体:

@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());
            }
        }
    }
...
公共类侦听器{
Logger log=LoggerFactory.getLogger(“TrimListener”);
@后装
public void repairAfterLoad(最终对象实体)引发IllegalAccessException{
调试(“trimlistener活动”);
最终设置trimProps=getTrimProperties(entity.getClass());
适用于(最终现场测试:trimProps){
最终字符串propertyValue=(字符串)fieldToTrim.get(实体);
if(propertyValue!=null){
fieldToTrim.set(entity,propertyValue.trim());
}
}
}
...

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

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


我已经对EntityListener进行了调整,以递归方式跟踪使用
Embeddeble
注释的字段。现在,如果一个实体使用了该侦听器,那么所有嵌入的类也会被处理:

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;
        }
    }
}
公共类侦听器{
@后装
public void trimAfterLoad(最终对象实体)引发IllegalAccessException{
最终设置trimProps=getTrimProperties(实体);
用于(最终可修剪修剪:修剪道具){
最终字符串propertyValue=(字符串)trimmable.field.get(trimmable.target);
if(propertyValue!=null){
trimmable.field.set(trimmable.target,propertyValue.trim());
}
}
}
私有集getTrimProperties(最终对象实体)引发IllegalAccessException{
最终类entityClass=entity.getClass();
final Set propertiesToTrim=新HashSet();
for(最终字段:entityClass.getDeclaredFields()){
if(field.getType().equals(String.class)&&(field.getAnnotation(Trim.class)!=null)){
字段。setAccessible(true);
propertiesToTrim.add(新的可微调(实体、字段));
//如果图元包含嵌入对象,则传播修剪
}else if(field.getType().getAnnotation(embeddeble.class)!=null){
字段。setAccessible(true);
propertiesToTrim.addAll(getTrimProperties(field.get(entity));
}
}
归还财产;
}
私人级可修剪{
最终目标;
最终字段;
公共可修剪(最终对象目标、最终字段){
this.target=目标;
this.field=字段;
}
}
}

谢谢,MaDa,这很有道理。我想我必须扩展侦听器以将修剪传播到嵌入式类。谢谢发布此Kostja;为我节省了一些时间!