如何在Hibernate PostUpdateEventListener中确定集合更改?

ala*_*irg 4 hibernate

在Hibernate中,实施PostUpdateEventListener允许你插入Hibernate的工作流程,让您有机会检查,当它被保存比较实体属性的新旧值(PostUpdateEvent有方法getOldState()的getState()返回一个这些值的数组).对于标准属性,这很好用.但是,如果其中一个属性是其内容已更改的Collection ,则没有任何帮助:"旧值"和"新值"都是对Collection的相同引用(因为Collection本身没有更改,只是它的内容).这意味着您只能看到该集合的最新即"新"内容.

任何人都知道是否有办法确定实体拥有的集合元素在工作流程中此时的变化情况如何?

ala*_*irg 7

我想出了一种方法来做到这一点,所以我会发布它,以防其他人使用它.此代码循环遍历所有"旧状态"属性,对于任何持久集合,它将获取先前内容的"快照".然后它将它包装在一个不可修改的集合中以获得良好的衡量标准:

public void onPostUpdate( PostUpdateEvent event )
{       
   for ( Object item: event.getOldState() )
   {
      Object previousContents = null;

      if ( item != null && item instanceof PersistentCollection )               
      {
         PersistentCollection pc = (PersistentCollection) item;
         PersistenceContext context = session.getPersistenceContext();            
         CollectionEntry entry = context.getCollectionEntry( pc );
         Object snapshot = entry.getSnapshot();

         if ( snapshot == null )
            continue;

         if ( pc instanceof List )
         {
            previousContents = Collections.unmodifiableList( (List) snapshot );
         }        
         else if ( pc instanceof Map )
         {
            previousContents = Collections.unmodifiableMap( (Map) snapshot );
         }
         else if ( pc instanceof Set )
         {  
            //Set snapshot is actually stored as a Map                
            Map snapshotMap = (Map) snapshot;
            previousContents = Collections.unmodifiableSet( new HashSet( snapshotMap.values() ) );          
         }
         else
           previousContents = pc;

      //Do something with previousContents here
  }   
Run Code Online (Sandbox Code Playgroud)