/** Overrides the default behaviour to including binding of Grails domain classes. */ @Override protected void secondPassCompile() throws MappingException { if (configLocked) { return; } // set the class loader to load Groovy classes if (grailsApplication != null) { Thread.currentThread().setContextClassLoader(grailsApplication.getClassLoader()); } configureDomainBinder(grailsApplication, domainClasses); for (GrailsDomainClass domainClass : domainClasses) { if (!GrailsHibernateUtil.usesDatasource(domainClass, dataSourceName)) { continue; } final Mappings mappings = super.createMappings(); Mapping m = binder.getMapping(domainClass); mappings.setAutoImport(m == null || m.getAutoImport()); binder.bindClass(domainClass, mappings, sessionFactoryBeanName); } super.secondPassCompile(); configLocked = true; }
/** Overrides the default behaviour to including binding of Grails domain classes. */ @Override protected void secondPassCompile() throws MappingException { final Thread currentThread = Thread.currentThread(); final ClassLoader originalContextLoader = currentThread.getContextClassLoader(); if (!configLocked) { if (LOG.isDebugEnabled()) LOG.debug( "[GrailsAnnotationConfiguration] [" + domainClasses.size() + "] Grails domain classes to bind to persistence runtime"); // do Grails class configuration configureDomainBinder(binder, grailsApplication, domainClasses); for (GrailsDomainClass domainClass : domainClasses) { final String fullClassName = domainClass.getFullName(); String hibernateConfig = fullClassName.replace('.', '/') + ".hbm.xml"; final ClassLoader loader = originalContextLoader; // don't configure Hibernate mapped classes if (loader.getResource(hibernateConfig) != null) continue; final Mappings mappings = super.createMappings(); if (!GrailsHibernateUtil.usesDatasource(domainClass, dataSourceName)) { continue; } LOG.debug( "[GrailsAnnotationConfiguration] Binding persistent class [" + fullClassName + "]"); Mapping m = binder.getMapping(domainClass); mappings.setAutoImport(m == null || m.getAutoImport()); binder.bindClass(domainClass, mappings, sessionFactoryBeanName); } } try { currentThread.setContextClassLoader(grailsApplication.getClassLoader()); super.secondPassCompile(); createSubclassForeignKeys(); } finally { currentThread.setContextClassLoader(originalContextLoader); } configLocked = true; }
private Iterator getSubPropertyIterator(PersistentClass pc, String reducedName) { Value value = pc.getRecursiveProperty(reducedName).getValue(); Iterator parentPropIter; if (value instanceof Component) { Component comp = (Component) value; parentPropIter = comp.getPropertyIterator(); } else if (value instanceof ToOne) { ToOne toOne = (ToOne) value; PersistentClass referencedPc = mappings.getClass(toOne.getReferencedEntityName()); if (toOne.getReferencedPropertyName() != null) { try { parentPropIter = ((Component) referencedPc .getRecursiveProperty(toOne.getReferencedPropertyName()) .getValue()) .getPropertyIterator(); } catch (ClassCastException e) { throw new MappingException( "dotted notation reference neither a component nor a many/one to one", e); } } else { try { if (referencedPc.getIdentifierMapper() == null) { parentPropIter = ((Component) referencedPc.getIdentifierProperty().getValue()).getPropertyIterator(); } else { parentPropIter = referencedPc.getIdentifierMapper().getPropertyIterator(); } } catch (ClassCastException e) { throw new MappingException( "dotted notation reference neither a component nor a many/one to one", e); } } } else { throw new MappingException( "dotted notation reference neither a component nor a many/one to one"); } return parentPropIter; }
@Override @SuppressWarnings("unchecked") protected SessionFactory buildSessionFactory() throws Exception { // Create Configuration instance. Configuration config = newConfiguration(); DataSource dataSource = getDataSource(); if (dataSource != null) { // Make given DataSource available for SessionFactory configuration. configTimeDataSourceHolder.set(dataSource); } if (this.jtaTransactionManager != null) { // Make Spring-provided JTA TransactionManager available. configTimeTransactionManagerHolder.set(this.jtaTransactionManager); } if (this.cacheRegionFactory != null) { // Make Spring-provided Hibernate RegionFactory available. configTimeRegionFactoryHolder.set(this.cacheRegionFactory); } if (this.lobHandler != null) { // Make given LobHandler available for SessionFactory configuration. // Do early because because mapping resource might refer to custom types. configTimeLobHandlerHolder.set(this.lobHandler); } // Analogous to Hibernate EntityManager's Ejb3Configuration: // Hibernate doesn't allow setting the bean ClassLoader explicitly, // so we need to expose it as thread context ClassLoader accordingly. Thread currentThread = Thread.currentThread(); ClassLoader threadContextClassLoader = currentThread.getContextClassLoader(); boolean overrideClassLoader = (this.beanClassLoader != null && !this.beanClassLoader.equals(threadContextClassLoader)); if (overrideClassLoader) { currentThread.setContextClassLoader(this.beanClassLoader); } try { if (isExposeTransactionAwareSessionFactory()) { // Set Hibernate 3.1+ CurrentSessionContext implementation, // providing the Spring-managed Session as current Session. // Can be overridden by a custom value for the corresponding Hibernate property. config.setProperty( Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName()); } if (this.jtaTransactionManager != null) { // Set Spring-provided JTA TransactionManager as Hibernate property. config.setProperty(Environment.TRANSACTION_STRATEGY, JTATransactionFactory.class.getName()); config.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, LocalTransactionManagerLookup.class.getName()); } else { // Makes the Hibernate Session aware of the presence of a Spring-managed transaction. // Also sets connection release mode to ON_CLOSE by default. config.setProperty( Environment.TRANSACTION_STRATEGY, SpringTransactionFactory.class.getName()); } if (this.entityInterceptor != null) { // Set given entity interceptor at SessionFactory level. config.setInterceptor(this.entityInterceptor); } if (this.namingStrategy != null) { // Pass given naming strategy to Hibernate Configuration. config.setNamingStrategy(this.namingStrategy); } if (this.typeDefinitions != null) { // Register specified Hibernate type definitions. Mappings mappings = config.createMappings(); for (TypeDefinitionBean typeDef : this.typeDefinitions) { mappings.addTypeDef( typeDef.getTypeName(), typeDef.getTypeClass(), typeDef.getParameters()); } } if (this.filterDefinitions != null) { // Register specified Hibernate FilterDefinitions. for (FilterDefinition filterDef : this.filterDefinitions) { config.addFilterDefinition(filterDef); } } if (this.configLocations != null) { for (Resource resource : this.configLocations) { // Load Hibernate configuration from given location. config.configure(resource.getURL()); } } if (this.hibernateProperties != null) { // Add given Hibernate properties to Configuration. config.addProperties(this.hibernateProperties); } if (dataSource != null) { Class<?> providerClass = LocalDataSourceConnectionProvider.class; if (isUseTransactionAwareDataSource() || dataSource instanceof TransactionAwareDataSourceProxy) { providerClass = TransactionAwareDataSourceConnectionProvider.class; } else if (config.getProperty(Environment.TRANSACTION_MANAGER_STRATEGY) != null) { providerClass = LocalJtaDataSourceConnectionProvider.class; } // Set Spring-provided DataSource as Hibernate ConnectionProvider. config.setProperty(Environment.CONNECTION_PROVIDER, providerClass.getName()); } if (this.cacheRegionFactory != null) { // Expose Spring-provided Hibernate RegionFactory. config.setProperty( Environment.CACHE_REGION_FACTORY, LocalRegionFactoryProxy.class.getName()); } if (this.mappingResources != null) { // Register given Hibernate mapping definitions, contained in resource files. for (String mapping : this.mappingResources) { Resource resource = new ClassPathResource(mapping.trim(), this.beanClassLoader); config.addInputStream(resource.getInputStream()); } } if (this.mappingLocations != null) { // Register given Hibernate mapping definitions, contained in resource files. for (Resource resource : this.mappingLocations) { config.addInputStream(resource.getInputStream()); } } if (this.cacheableMappingLocations != null) { // Register given cacheable Hibernate mapping definitions, read from the file system. for (Resource resource : this.cacheableMappingLocations) { config.addCacheableFile(resource.getFile()); } } if (this.mappingJarLocations != null) { // Register given Hibernate mapping definitions, contained in jar files. for (Resource resource : this.mappingJarLocations) { config.addJar(resource.getFile()); } } if (this.mappingDirectoryLocations != null) { // Register all Hibernate mapping definitions in the given directories. for (Resource resource : this.mappingDirectoryLocations) { File file = resource.getFile(); if (!file.isDirectory()) { throw new IllegalArgumentException( "Mapping directory location [" + resource + "] does not denote a directory"); } config.addDirectory(file); } } // Tell Hibernate to eagerly compile the mappings that we registered, // for availability of the mapping information in further processing. postProcessMappings(config); config.buildMappings(); if (this.entityCacheStrategies != null) { // Register cache strategies for mapped entities. for (Enumeration<?> classNames = this.entityCacheStrategies.propertyNames(); classNames.hasMoreElements(); ) { String className = (String) classNames.nextElement(); String[] strategyAndRegion = StringUtils.commaDelimitedListToStringArray( this.entityCacheStrategies.getProperty(className)); if (strategyAndRegion.length > 1) { config.setCacheConcurrencyStrategy( className, strategyAndRegion[0], strategyAndRegion[1]); } else if (strategyAndRegion.length > 0) { config.setCacheConcurrencyStrategy(className, strategyAndRegion[0]); } } } if (this.collectionCacheStrategies != null) { // Register cache strategies for mapped collections. for (Enumeration<?> collRoles = this.collectionCacheStrategies.propertyNames(); collRoles.hasMoreElements(); ) { String collRole = (String) collRoles.nextElement(); String[] strategyAndRegion = StringUtils.commaDelimitedListToStringArray( this.collectionCacheStrategies.getProperty(collRole)); if (strategyAndRegion.length > 1) { config.setCollectionCacheConcurrencyStrategy( collRole, strategyAndRegion[0], strategyAndRegion[1]); } else if (strategyAndRegion.length > 0) { config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0]); } } } if (this.eventListeners != null) { // Register specified Hibernate event listeners. for (Map.Entry<String, Object> entry : this.eventListeners.entrySet()) { String listenerType = entry.getKey(); Object listenerObject = entry.getValue(); if (listenerObject instanceof Collection) { Collection<Object> listeners = (Collection<Object>) listenerObject; EventListeners listenerRegistry = config.getEventListeners(); Object[] listenerArray = (Object[]) Array.newInstance( listenerRegistry.getListenerClassFor(listenerType), listeners.size()); listenerArray = listeners.toArray(listenerArray); config.setListeners(listenerType, listenerArray); } else { config.setListener(listenerType, listenerObject); } } } // Perform custom post-processing in subclasses. postProcessConfiguration(config); // Build SessionFactory instance. logger.info("Building new Hibernate SessionFactory"); this.configuration = config; return newSessionFactory(config); } finally { if (dataSource != null) { configTimeDataSourceHolder.remove(); } if (this.jtaTransactionManager != null) { configTimeTransactionManagerHolder.remove(); } if (this.cacheRegionFactory != null) { configTimeRegionFactoryHolder.remove(); } if (this.lobHandler != null) { configTimeLobHandlerHolder.remove(); } if (overrideClassLoader) { // Reset original thread context ClassLoader. currentThread.setContextClassLoader(threadContextClassLoader); } } }
public void doSecondPass(Map persistentClasses) throws MappingException { // TODO add parameters checkings if (ann == null) return; ResultSetMappingDefinition definition = new ResultSetMappingDefinition(ann.name()); LOG.debugf("Binding result set mapping: %s", definition.getName()); int entityAliasIndex = 0; for (EntityResult entity : ann.entities()) { // TODO parameterize lock mode? List<FieldResult> properties = new ArrayList<FieldResult>(); List<String> propertyNames = new ArrayList<String>(); for (FieldResult field : entity.fields()) { // use an ArrayList cause we might have several columns per root property String name = field.name(); if (name.indexOf('.') == -1) { // regular property properties.add(field); propertyNames.add(name); } else { /** * Reorder properties 1. get the parent property 2. list all the properties following the * expected one in the parent property 3. calculate the lowest index and insert the * property */ PersistentClass pc = mappings.getClass(entity.entityClass().getName()); if (pc == null) { throw new MappingException( "Entity not found " + entity.entityClass().getName() + " in SqlResultsetMapping " + ann.name()); } int dotIndex = name.lastIndexOf('.'); String reducedName = name.substring(0, dotIndex); Iterator parentPropIter = getSubPropertyIterator(pc, reducedName); List followers = getFollowers(parentPropIter, reducedName, name); int index = propertyNames.size(); int followersSize = followers.size(); for (int loop = 0; loop < followersSize; loop++) { String follower = (String) followers.get(loop); int currentIndex = getIndexOfFirstMatchingProperty(propertyNames, follower); index = currentIndex != -1 && currentIndex < index ? currentIndex : index; } propertyNames.add(index, name); properties.add(index, field); } } Set<String> uniqueReturnProperty = new HashSet<String>(); Map<String, ArrayList<String>> propertyResultsTmp = new HashMap<String, ArrayList<String>>(); for (Object property : properties) { final FieldResult propertyresult = (FieldResult) property; final String name = propertyresult.name(); if ("class".equals(name)) { throw new MappingException( "class is not a valid property name to use in a @FieldResult, use @Entity(discriminatorColumn) instead"); } if (uniqueReturnProperty.contains(name)) { throw new MappingException( "duplicate @FieldResult for property " + name + " on @Entity " + entity.entityClass().getName() + " in " + ann.name()); } uniqueReturnProperty.add(name); final String quotingNormalizedColumnName = mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(propertyresult.column()); String key = StringHelper.root(name); ArrayList<String> intermediateResults = propertyResultsTmp.get(key); if (intermediateResults == null) { intermediateResults = new ArrayList<String>(); propertyResultsTmp.put(key, intermediateResults); } intermediateResults.add(quotingNormalizedColumnName); } Map<String, String[]> propertyResults = new HashMap<String, String[]>(); for (Map.Entry<String, ArrayList<String>> entry : propertyResultsTmp.entrySet()) { propertyResults.put( entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()])); } if (!BinderHelper.isEmptyAnnotationValue(entity.discriminatorColumn())) { final String quotingNormalizedName = mappings .getObjectNameNormalizer() .normalizeIdentifierQuoting(entity.discriminatorColumn()); propertyResults.put("class", new String[] {quotingNormalizedName}); } if (propertyResults.isEmpty()) { propertyResults = java.util.Collections.emptyMap(); } NativeSQLQueryRootReturn result = new NativeSQLQueryRootReturn( "alias" + entityAliasIndex++, entity.entityClass().getName(), propertyResults, LockMode.READ); definition.addQueryReturn(result); } for (ColumnResult column : ann.columns()) { definition.addQueryReturn( new NativeSQLQueryScalarReturn( mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(column.name()), null)); } for (ConstructorResult constructorResult : ann.classes()) { List<NativeSQLQueryScalarReturn> columnReturns = new ArrayList<NativeSQLQueryScalarReturn>(); for (ColumnResult columnResult : constructorResult.columns()) { columnReturns.add( new NativeSQLQueryScalarReturn( mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(columnResult.name()), null)); } definition.addQueryReturn( new NativeSQLQueryConstructorReturn(constructorResult.targetClass(), columnReturns)); } if (isDefault) { mappings.addDefaultResultSetMapping(definition); } else { mappings.addResultSetMapping(definition); } }