2012-11-15 33 views
4

我有一個EmebeddedId的實體。正如預期的那樣,正在觸發實體上的實體監聽器(在加載時修剪空白空間Strings),因此根本沒有觸發編號爲Embeddable的相同監聽器。如何觸發可嵌入的EntityListener

我做錯了嗎?它如何被修復?

實體:

@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()); 
      } 
     } 
    } 
... 

回答

3

我認爲這顯然忽略,因爲它不是一個標準的地方,JPA 2.0期望它。根據JPA 2.0最終規格,實體聽衆可以是實體,映射超或在其中的一個相關聯的監聽器(見該規範的第3.5節):

的方法,可以被指定爲一個生命週期回調方法來接收實體生命週期事件的通知。甲生命週期回調方法可以在一個實體類,映射超,或與實體相關聯或映射超

+0

感謝,MADA,非常有意義。我想我必須擴展偵聽器來傳播修剪到嵌入類。 – kostja

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; 
     } 
    } 
} 
+0

感謝您發佈此Kostja;爲我節省了一些時間! –

+0

@Brando_Calrissian - 酷,不客氣:) – kostja