/**
  * Add order to criteria, creating necessary subCriteria if nested sort property (ie.
  * sort:'nested.property').
  */
 private static void addOrderPossiblyNested(
     AbstractHibernateDatastore datastore,
     Criteria c,
     Class<?> targetClass,
     String sort,
     String order,
     boolean ignoreCase) {
   int firstDotPos = sort.indexOf(".");
   if (firstDotPos == -1) {
     addOrder(c, sort, order, ignoreCase);
   } else { // nested property
     String sortHead = sort.substring(0, firstDotPos);
     String sortTail = sort.substring(firstDotPos + 1);
     PersistentProperty property = getGrailsDomainClassProperty(datastore, targetClass, sortHead);
     if (property instanceof Embedded) {
       // embedded objects cannot reference entities (at time of writing), so no more recursion
       // needed
       addOrder(c, sort, order, ignoreCase);
     } else if (property instanceof Association) {
       Criteria subCriteria = c.createCriteria(sortHead);
       Class<?> propertyTargetClass =
           ((Association) property).getAssociatedEntity().getJavaClass();
       GrailsHibernateUtil.cacheCriteriaByMapping(datastore, propertyTargetClass, subCriteria);
       addOrderPossiblyNested(
           datastore,
           subCriteria,
           propertyTargetClass,
           sortTail,
           order,
           ignoreCase); // Recurse on nested sort
     }
   }
 }
  /** 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;
  }
 public void configureDomainBinder(
     GrailsDomainBinder binder,
     GrailsApplication grailsApplication,
     Set<GrailsDomainClass> domainClasses) {
   GrailsHibernateUtil.setDomainBinder(binder);
   Closure defaultMapping =
       grailsApplication
           .getConfig()
           .getProperty(GrailsDomainConfiguration.DEFAULT_MAPPING, Closure.class);
   // do Grails class configuration
   if (defaultMapping != null) {
     binder.setDefaultMapping(defaultMapping);
   }
   for (GrailsDomainClass domainClass : domainClasses) {
     if (defaultMapping != null) {
       binder.evaluateMapping(domainClass, defaultMapping);
     } else {
       binder.evaluateMapping(domainClass);
     }
   }
 }
  @Override
  public SessionFactory buildSessionFactory() throws HibernateException {

    // set the class loader to load Groovy classes
    if (grailsApplication != null) {
      LOG.debug(
          "[GrailsAnnotationConfiguration] Setting context class loader to Grails GroovyClassLoader");
      Thread.currentThread().setContextClassLoader(grailsApplication.getClassLoader());
    }

    // work around for HHH-2624
    Map<String, Type> empty = new HashMap<String, Type>();
    addFilterDefinition(new FilterDefinition("dynamicFilterEnabler", "1=1", empty));

    SessionFactory sessionFactory = null;

    ClassLoader appClassLoader =
        (ClassLoader) getProperties().get(AvailableSettings.APP_CLASSLOADER);
    Thread currentThread = Thread.currentThread();
    ClassLoader threadContextClassLoader = currentThread.getContextClassLoader();
    boolean overrideClassLoader =
        (appClassLoader != null && !appClassLoader.equals(threadContextClassLoader));
    if (overrideClassLoader) {
      currentThread.setContextClassLoader(appClassLoader);
    }

    try {
      ConfigurationHelper.resolvePlaceHolders(getProperties());

      EventListenerIntegrator eventListenerIntegrator =
          new EventListenerIntegrator(hibernateEventListeners, eventListeners);
      BootstrapServiceRegistry bootstrapServiceRegistry =
          new BootstrapServiceRegistryBuilder().with(eventListenerIntegrator).build();

      setSessionFactoryObserver(
          new SessionFactoryObserver() {
            private static final long serialVersionUID = 1;

            public void sessionFactoryCreated(SessionFactory factory) {}

            public void sessionFactoryClosed(SessionFactory factory) {
              ((ServiceRegistryImplementor) serviceRegistry).destroy();
            }
          });

      StandardServiceRegistryBuilder standardServiceRegistryBuilder =
          new StandardServiceRegistryBuilder(bootstrapServiceRegistry)
              .applySettings(getProperties());
      sessionFactory = super.buildSessionFactory(standardServiceRegistryBuilder.build());
      serviceRegistry = ((SessionFactoryImplementor) sessionFactory).getServiceRegistry();
    } finally {
      if (overrideClassLoader) {
        currentThread.setContextClassLoader(threadContextClassLoader);
      }
    }

    if (grailsApplication != null) {
      GrailsHibernateUtil.configureHibernateDomainClasses(
          sessionFactory, sessionFactoryBeanName, grailsApplication);
    }

    return sessionFactory;
  }