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);
}
}