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
。实体上的实体侦听器(加载时修剪空白字符串
)正在按预期触发,idEmbedded
上的同一侦听器根本不会触发
我做错了吗?怎么能修好呢
实体:
@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;为我节省了一些时间!