2017-09-20 3 views
1

Ich benutze Frühling, Winterschlaf, jpa2.1. wie folgt:wie Entity Listener programmierbar in Hibernate JPA

@Entity 
@EntityListeners(DemoListener.class) 
public class Demo { 

    @Id 
    private Long id; 

    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 
} 

public class DemoListener { 

    @PersistenceContext 
    private EntityManager entityManager; 

    @PrePersist 
    public void prePersist(Demo demo){ 

    } 
} 

das Beispiel funktioniert gut, wenn ich will mehr Zuhörer an, ich muß die Demo Einheit ändern, aber die Demo ist in anderem Glas, ich will nicht die XML-Konfiguration verwenden, ist es wie diese eine Möglichkeit:

...addListener(Demo.class, new DemoListener()); 
...addListener(Demo.class, new OtherDemoListener()); 

Antwort

0

Basis auf hibernate-orm docs und hibernate-Tutorials:

/** 
* @param <T> one of {@link EventType#baseListenerInterface()} 
* @see org.hibernate.event.service.spi.EventListenerRegistry 
*/ 
public interface JpaEventListenerRegistry<T> { 

    /** 
    * add listener for entity class 
    * 
    * @param entityClass can't be null 
    * @param listener can't be null 
    */ 
    void addListener(Class<?> entityClass, T listener); 
} 



public class JpaEventListenerRegistryImpl implements JpaEventListenerRegistry<Object> { 

    private Logger logger = LoggerFactory.getLogger(getClass()); 

    private EventListenerRegistry eventListenerRegistry; 
    private Map<EventType, JpaEventListenerRegistry> listeners = new HashMap<EventType, JpaEventListenerRegistry>(); 

    public JpaEventListenerRegistryImpl(EventListenerRegistry eventListenerRegistry) { 
     this.eventListenerRegistry = eventListenerRegistry; 
     initDefault(); 
    } 

    private void initDefault() { 
     listeners.put(EventType.PRE_INSERT, new DomainPreInsertEventListener()); 
     listeners.put(EventType.POST_INSERT, new DomainPostInsertEventListener()); 
     for (Map.Entry<EventType, JpaEventListenerRegistry> entry : listeners.entrySet()) { 
      eventListenerRegistry.appendListeners(entry.getKey(), entry.getValue()); 
     } 
    } 

    @SuppressWarnings("unchecked") 
    public void addListener(Class<?> entityClass, Object listener) { 
     logger.info("add listener {} for entity {}", listener, entityClass.getName()); 
     for (EventType eventType : EventType.values()) { 
      Class<?> listenerInterface = eventType.baseListenerInterface(); 
      if (listenerInterface.isAssignableFrom(listener.getClass())) { 
       JpaEventListenerRegistry registry = listeners.get(eventType); 
       if (registry == null) { 
        logger.warn("the event type {} for listener {} is not supported", eventType, listener); 
       } else { 
        registry.addListener(entityClass, listener); 
       } 
      } 
     } 
    } 

    public static class Abstract<T> implements JpaEventListenerRegistry<T> { 

     private Logger logger = LoggerFactory.getLogger(getClass()); 
     private Map<Class<?>, List<T>> listeners = new HashMap<Class<?>, List<T>>(); 

     public void addListener(Class<?> entityClass, T listener) { 
      logger.info("add listener {} for entity {}", listener, entityClass.getName()); 
      List<T> listeners = this.listeners.get(entityClass); 
      if (listeners == null) { 
       listeners = new ArrayList<T>(); 
       this.listeners.put(entityClass, listeners); 
      } 
      listeners.add(listener); 
     } 

     List<T> findListener(Class<?> entityClass) { 
      for (Map.Entry<Class<?>, List<T>> entry : listeners.entrySet()) { 
       if (entry.getKey().isAssignableFrom(entityClass)) { 
        return entry.getValue(); 
       } 
      } 
      return null; 
     } 

    } 


    public static class DomainPreInsertEventListener extends Abstract<PreInsertEventListener> implements PreInsertEventListener { 

     public boolean onPreInsert(PreInsertEvent event) { 
      return onPreInsert(event, findListener(event.getEntity().getClass())); 
     } 

     private boolean onPreInsert(PreInsertEvent event, List<PreInsertEventListener> listeners) { 
      if (listeners == null) return false; 
      for (PreInsertEventListener listener : listeners) { 
       if (listener.onPreInsert(event)) return true; 
      } 
      return false; 
     } 
    } 

    public static class DomainPostInsertEventListener extends Abstract<PostInsertEventListener> implements PostInsertEventListener { 

     public void onPostInsert(PostInsertEvent event) { 
      onPostInsert(event, findListener(event.getEntity().getClass())); 
     } 

     private void onPostInsert(PostInsertEvent event, List<PostInsertEventListener> listeners) { 
      if (listeners == null) return; 
      for (PostInsertEventListener listener : listeners) { 
       listener.onPostInsert(event); 
      } 
     } 


     public boolean requiresPostCommitHanding(EntityPersister persister) { 
      return false; 
     } 
    } 
} 


public class EntityManagerIllustrationTest extends TestCase { 
    private EntityManagerFactory entityManagerFactory; 

    @Override 
    protected void setUp() throws Exception { 
     // like discussed with regards to SessionFactory, an EntityManagerFactory is set up once for an application 
     //  IMPORTANT: notice how the name here matches the name we gave the persistence-unit in persistence.xml! 
     entityManagerFactory = Persistence.createEntityManagerFactory("org.hibernate.tutorial.jpa"); 

     SessionFactoryImplementor sessionFactory = entityManagerFactory.unwrap(SessionFactoryImplementor.class); 
     EventListenerRegistry eventListenerRegistry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class); 
     JpaEventListenerRegistryImpl jpaEventListenerRegistry = new JpaEventListenerRegistryImpl(eventListenerRegistry); 
     jpaEventListenerRegistry.addListener(EventListener.class, new JpaEventListener()); 
    } 

    private static class JpaEventListener implements PreInsertEventListener, PostInsertEventListener { 
     public boolean onPreInsert(PreInsertEvent event) { 
      Event entity = (Event) event.getEntity(); 
      System.out.println("onPreInsert:" + entity); 
      return false; 
     } 

     public void onPostInsert(PostInsertEvent event) { 
      Event entity = (Event) event.getEntity(); 
      System.out.println("onPostInsert:" + entity); 
     } 

     public boolean requiresPostCommitHanding(EntityPersister persister) { 
      return false; 
     } 
    } 

    @Override 
    protected void tearDown() throws Exception { 
     entityManagerFactory.close(); 
    } 

    public void testBasicUsage() { 
     // create a couple of events... 
     EntityManager entityManager = entityManagerFactory.createEntityManager(); 
     entityManager.getTransaction().begin(); 
     entityManager.persist(new Event("Our very first event!", new Date())); 
//  entityManager.persist(new Event("A follow up event", new Date())); 
     entityManager.getTransaction().commit(); 
     entityManager.close(); 

     // now lets pull events from the database and list them 
     entityManager = entityManagerFactory.createEntityManager(); 
     entityManager.getTransaction().begin(); 
     List<Event> result = entityManager.createQuery("from Event", Event.class).getResultList(); 
     for (Event event : result) { 
      System.out.println("Event (" + event.getDate() + ") : " + event.getTitle()); 
     } 
     entityManager.getTransaction().commit(); 
     entityManager.close(); 
    } 


}