HHH-5913 - Implement set of event listeners as a service

This commit is contained in:
Steve Ebersole 2011-03-26 22:04:36 -05:00
parent e8ebe8e396
commit c28b553f21
7 changed files with 115 additions and 15 deletions

View File

@ -99,7 +99,6 @@ import org.hibernate.engine.profile.FetchProfile;
import org.hibernate.engine.query.QueryPlanCache;
import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
import org.hibernate.engine.transaction.spi.TransactionEnvironment;
import org.hibernate.event.EventListeners;
import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.UUIDGenerator;
@ -183,7 +182,7 @@ public final class SessionFactoryImpl
private final transient Map fetchProfiles;
private final transient Map imports;
private final transient Interceptor interceptor;
private final transient ServiceRegistryImplementor serviceRegistry;
private final transient SessionFactoryServiceRegistry serviceRegistry;
private final transient Settings settings;
private final transient Properties properties;
private transient SchemaExport schemaExport;

View File

@ -23,10 +23,13 @@
*/
package org.hibernate.service.internal;
import java.util.List;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.service.Service;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.SessionFactoryServiceInitiator;
import org.hibernate.service.spi.SessionFactoryServiceRegistryFactory;
/**

View File

@ -23,10 +23,23 @@
*/
package org.hibernate.service.internal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jboss.logging.Logger;
import org.hibernate.HibernateLogger;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.service.Service;
import org.hibernate.service.StandardSessionFactoryServiceInitiators;
import org.hibernate.service.UnknownServiceException;
import org.hibernate.service.spi.BasicServiceInitiator;
import org.hibernate.service.spi.ServiceException;
import org.hibernate.service.spi.ServiceRegistryAwareService;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.SessionFactoryServiceInitiator;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
/**
@ -36,27 +49,84 @@ public class SessionFactoryServiceRegistryImpl
extends AbstractServiceRegistryImpl
implements SessionFactoryServiceRegistry {
private final SessionFactoryImplementor sessionFactory;
private Configuration configuration;
private static final HibernateLogger LOG = Logger.getMessageLogger( HibernateLogger.class, SessionFactoryServiceRegistryImpl.class.getName() );
private final Map<Class,SessionFactoryServiceInitiator> serviceInitiatorMap;
// for now we need to hold on to the Configuration... :(
private Configuration configuration;
private final SessionFactoryImplementor sessionFactory;
@SuppressWarnings( {"unchecked"})
public SessionFactoryServiceRegistryImpl(
ServiceRegistryImplementor parent,
SessionFactoryImplementor sessionFactory,
Configuration configuration) {
super( parent );
// for now, just use the standard initiator list
this.serviceInitiatorMap = toMap( StandardSessionFactoryServiceInitiators.LIST );
this.sessionFactory = sessionFactory;
this.configuration = configuration;
for ( SessionFactoryServiceInitiator initiator : serviceInitiatorMap.values() ) {
// create the bindings up front to help identify to which registry services belong
createServiceBinding( initiator.getServiceInitiated() );
}
}
private static Map<Class, SessionFactoryServiceInitiator> toMap(List<SessionFactoryServiceInitiator> serviceInitiators) {
final Map<Class, SessionFactoryServiceInitiator> result = new HashMap<Class, SessionFactoryServiceInitiator>();
for ( SessionFactoryServiceInitiator initiator : serviceInitiators ) {
result.put( initiator.getServiceInitiated(), initiator );
}
return result;
}
@Override
@SuppressWarnings( {"unchecked"})
public void registerServiceInitiator(SessionFactoryServiceInitiator initiator) {
ServiceBinding serviceBinding = locateServiceBinding( initiator.getServiceInitiated(), false );
if ( serviceBinding != null ) {
serviceBinding.setTarget( null );
}
else {
createServiceBinding( initiator.getServiceInitiated() );
}
final Object previous = serviceInitiatorMap.put( initiator.getServiceInitiated(), initiator );
if ( previous != null ) {
LOG.debugf( "Over-wrote existing service initiator [role=%s]", initiator.getServiceInitiated().getName() );
}
}
@Override
@SuppressWarnings({ "unchecked" })
protected <T extends Service> T createService(Class<T> serviceRole) {
return null; // todo : implement method body
SessionFactoryServiceInitiator<T> initiator = serviceInitiatorMap.get( serviceRole );
if ( initiator == null ) {
throw new UnknownServiceException( serviceRole );
}
try {
T service = initiator.initiateService( sessionFactory, configuration, this );
// IMPL NOTE : the register call here is important to avoid potential stack overflow issues
// from recursive calls through #configureService
registerService( serviceRole, service );
return service;
}
catch ( ServiceException e ) {
throw e;
}
catch ( Exception e ) {
throw new ServiceException( "Unable to create requested service [" + serviceRole.getName() + "]", e );
}
}
@Override
protected <T extends Service> void configureService(T service) {
// todo : implement method body
applyInjections( service );
if ( ServiceRegistryAwareService.class.isInstance( service ) ) {
( (ServiceRegistryAwareService) service ).injectServices( this );
}
}
}

View File

@ -30,5 +30,5 @@ package org.hibernate.service.spi;
* @author Steve Ebersole
*/
public interface SessionFactoryServiceRegistry extends ServiceRegistryImplementor {
// todo : add regsitration of service initiator
public void registerServiceInitiator(SessionFactoryServiceInitiator initiator);
}

View File

@ -23,6 +23,8 @@
*/
package org.hibernate.service.spi;
import java.util.List;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.service.Service;

View File

@ -22,6 +22,7 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.test.events;
import java.util.Map;
import java.util.Set;
import org.hibernate.HibernateException;
@ -31,8 +32,10 @@ import org.hibernate.cfg.Configuration;
import org.hibernate.event.DeleteEvent;
import org.hibernate.event.DeleteEventListener;
import org.hibernate.event.Destructible;
import org.hibernate.event.EventListenerRegistration;
import org.hibernate.event.EventType;
import org.hibernate.event.Initializable;
import org.hibernate.service.StandardServiceInitiators;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.service.internal.BasicServiceRegistryImpl;
import org.hibernate.service.spi.ServiceRegistryImplementor;
@ -65,7 +68,17 @@ public class CallbackTest extends BaseCoreFunctionalTestCase {
@Override
protected void applyServices(BasicServiceRegistryImpl serviceRegistry) {
super.applyServices( serviceRegistry );
serviceRegistry.getService( EventListenerRegistry.class ).setListeners( EventType.DELETE, listener );
serviceRegistry.getService( StandardServiceInitiators.EventListenerRegistrationService.class ).attachEventListenerRegistration(
new EventListenerRegistration() {
@Override
public void apply(
ServiceRegistryImplementor serviceRegistry,
Configuration configuration,
Map<?, ?> configValues) {
serviceRegistry.getService( EventListenerRegistry.class ).setListeners( EventType.DELETE, listener );
}
}
);
}
@Test

View File

@ -25,11 +25,13 @@ package org.hibernate.test.jpa;
import javax.persistence.EntityNotFoundException;
import java.io.Serializable;
import java.util.Map;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.CascadingAction;
import org.hibernate.event.AutoFlushEventListener;
import org.hibernate.event.EventListenerRegistration;
import org.hibernate.event.EventType;
import org.hibernate.event.FlushEntityEventListener;
import org.hibernate.event.FlushEventListener;
@ -40,8 +42,10 @@ import org.hibernate.event.def.DefaultFlushEventListener;
import org.hibernate.event.def.DefaultPersistEventListener;
import org.hibernate.internal.util.collections.IdentityMap;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.service.StandardServiceInitiators;
import org.hibernate.service.event.spi.EventListenerRegistry;
import org.hibernate.service.internal.BasicServiceRegistryImpl;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
@ -67,13 +71,22 @@ public abstract class AbstractJPATest extends BaseCoreFunctionalTestCase {
@Override
protected void applyServices(BasicServiceRegistryImpl serviceRegistry) {
super.applyServices( serviceRegistry );
EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
eventListenerRegistry.setListeners( EventType.PERSIST, buildPersistEventListeners() );
eventListenerRegistry.setListeners( EventType.PERSIST_ONFLUSH, buildPersisOnFlushEventListeners() );
eventListenerRegistry.setListeners( EventType.AUTO_FLUSH, buildAutoFlushEventListeners() );
eventListenerRegistry.setListeners( EventType.FLUSH, buildFlushEventListeners() );
eventListenerRegistry.setListeners( EventType.FLUSH_ENTITY, buildFlushEntityEventListeners() );
serviceRegistry.getService( StandardServiceInitiators.EventListenerRegistrationService.class ).attachEventListenerRegistration(
new EventListenerRegistration() {
@Override
public void apply(
ServiceRegistryImplementor serviceRegistry,
Configuration configuration,
Map<?, ?> configValues) {
EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );
eventListenerRegistry.setListeners( EventType.PERSIST, buildPersistEventListeners() );
eventListenerRegistry.setListeners( EventType.PERSIST_ONFLUSH, buildPersisOnFlushEventListeners() );
eventListenerRegistry.setListeners( EventType.AUTO_FLUSH, buildAutoFlushEventListeners() );
eventListenerRegistry.setListeners( EventType.FLUSH, buildFlushEventListeners() );
eventListenerRegistry.setListeners( EventType.FLUSH_ENTITY, buildFlushEntityEventListeners() );
}
}
);
}
@Override