import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.event.internal.DefaultMergeEventListener; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl; import org.hibernate.type.Type; import java.util.Map; public class IgnoreNullEventListener extends DefaultMergeEventListener { public static final IgnoreNullEventListener INSTANCE = new IgnoreNullEventListener(); @Override protected void copyValues(EntityPersister persister, Object entity, Object target, SessionImplementor source, Map copyCache) { //源目标 Object[] original = persister.getPropertyValues( entity ); //存储目标 Object[] targets = persister.getPropertyValues(target); Type[] types = persister.getPropertyTypes(); Object[] copied = new Object[original.length]; for ( int i = 0; i < types.length; i++ ) { if ( original[i] == null || original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY || original[i] == PropertyAccessStrategyBackRefImpl.UNKNOWN ){ copied[i] = targets[i]; } else { copied[i] = types[i].replace( original[i], targets[i], source, target, copyCache ); } } persister.setPropertyValues( target, copied ); } }
import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventType; import org.hibernate.internal.SessionFactoryImpl; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import javax.persistence.EntityManagerFactory; import javax.persistence.PersistenceUnit; @Configuration public class HibernateListenerConfigurer { @PersistenceUnit private EntityManagerFactory emf; @PostConstruct protected void init() { SessionFactoryImpl sessionFactory = emf.unwrap(SessionFactoryImpl.class); EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class); registry.getEventListenerGroup(EventType.MERGE).clear(); registry.getEventListenerGroup(EventType.MERGE).prependListener(IgnoreNullEventListener.INSTANCE); } }