我有一个EmebeddedId
的实体。正在按预期触发实体监听器(在加载时修剪Strings
关闭空白)实体监听器,ID Embeddable
上的同一监听器根本不会被触发。
我做错了吗?如何解决?
实体:
@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());
}
}
}
...
答案 0 :(得分:3)
我认为它显然被忽略了,因为它不是JPA 2.0所期望的标准场所。根据JPA 2.0最终规范,实体监听器可以是实体,映射的超类或与其中一个相关联的监听器(参见规范的第3.5节):
可以将方法指定为生命周期回调方法,以接收实体生命周期的通知 事件。可以在实体类,映射的超类或实体上定义生命周期回调方法 与实体或映射的超类相关联的侦听器类
答案 1 :(得分: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;
}
}
}