@SuppressWarnings( "unchecked" ) public EntityManagerFactoryImpl( SessionFactory sessionFactory, PersistenceUnitTransactionType transactionType, boolean discardOnClose, Class<?> sessionInterceptorClass, Configuration cfg) { this.sessionFactory = sessionFactory; this.transactionType = transactionType; this.discardOnClose = discardOnClose; this.sessionInterceptorClass = sessionInterceptorClass; final Iterator<PersistentClass> classes = cfg.getClassMappings(); List<PersistentClass> persistentClasses = new ArrayList<PersistentClass>(); while (classes.hasNext()) { PersistentClass persistentClass = classes.next(); // Hardcode jBPM classes for now, but make tidy with a property like "hibernate.ejb.metamodel.excluded.pkgs" if (persistentClass.getClassName().startsWith("org.jbpm")) { continue; } else { persistentClasses.add(persistentClass); } } //a safe guard till we are confident that metamodel is wll tested if ( !"disabled".equalsIgnoreCase( cfg.getProperty( "hibernate.ejb.metamodel.generation" ) ) ) { this.metamodel = MetamodelImpl.buildMetamodel( persistentClasses.iterator(), ( SessionFactoryImplementor ) sessionFactory ); } else { this.metamodel = null; } this.criteriaBuilder = new CriteriaBuilderImpl( this ); this.util = new HibernatePersistenceUnitUtil( this ); HashMap<String,Object> props = new HashMap<String, Object>(); addAll( props, ( (SessionFactoryImplementor) sessionFactory ).getProperties() ); addAll( props, cfg.getProperties() ); this.properties = Collections.unmodifiableMap( props ); }
@SuppressWarnings({"rawtypes", "unchecked", "serial"}) public Path getPath(From root, FieldPath fieldPath, final CriteriaBuilder builder) { FieldPath myFieldPath = fieldPath; if (!StringUtils.isEmpty(fieldPath.getTargetProperty())) { myFieldPath = getFieldPath(root, fieldPath.getTargetProperty()); } From myRoot = root; for (String pathElement : myFieldPath.getAssociationPath()) { myRoot = myRoot.join(pathElement); } Path path = myRoot; for (int i = 0; i < myFieldPath.getTargetPropertyPieces().size(); i++) { String piece = myFieldPath.getTargetPropertyPieces().get(i); if (path.getJavaType().isAnnotationPresent(Embeddable.class)) { String original = ((SingularAttributePath) path).getAttribute().getDeclaringType().getJavaType().getName() + "." + ((SingularAttributePath) path).getAttribute().getName() + "." + piece; String copy = path.getJavaType().getName() + "." + piece; copyCollectionPersister(original, copy, ((CriteriaBuilderImpl) builder).getEntityManagerFactory().getSessionFactory()); } try { path = path.get(piece); } catch (IllegalArgumentException e) { // We weren't able to resolve the requested piece, likely because it's in a polymoprhic version // of the path we're currently on. Let's see if there's any polymoprhic version of our class to // use instead. EntityManagerFactoryImpl em = ((CriteriaBuilderImpl) builder).getEntityManagerFactory(); Metamodel mm = em.getMetamodel(); boolean found = false; Class<?>[] polyClasses = dynamicDaoHelper.getAllPolymorphicEntitiesFromCeiling( path.getJavaType(), em.getSessionFactory(), true, true); for (Class<?> clazz : polyClasses) { ManagedType mt = mm.managedType(clazz); try { Attribute attr = mt.getAttribute(piece); if (attr != null) { Root additionalRoot = criteria.from(clazz); restrictions.add(builder.equal(path, additionalRoot)); path = additionalRoot.get(piece); found = true; break; } } catch (IllegalArgumentException e2) { // Do nothing - we'll try the next class and see if it has the attribute } } if (!found) { throw new IllegalArgumentException("Could not resolve requested attribute against path, including" + " known polymorphic versions of the root", e); } } if (path.getParentPath() != null && path.getParentPath().getJavaType().isAnnotationPresent(Embeddable.class) && path instanceof PluralAttributePath) { //We need a workaround for this problem until it is resolved in Hibernate (loosely related to and likely resolved by https://hibernate.atlassian.net/browse/HHH-8802) //We'll throw a specialized exception (and handle in an alternate flow for calls from BasicPersistenceModule) throw new CriteriaConversionException(String.format("Unable to create a JPA criteria Path through an @Embeddable object to a collection that resides therein (%s)", fieldPath.getTargetProperty()), fieldPath); // //TODO this code should work, but there still appear to be bugs in Hibernate's JPA criteria handling for lists // //inside Embeddables // Class<?> myClass = ((PluralAttributePath) path).getAttribute().getClass().getInterfaces()[0]; // //we don't know which version of "join" to call, so we'll let reflection figure it out // try { // From embeddedJoin = myRoot.join(((SingularAttributePath) path.getParentPath()).getAttribute()); // Method join = embeddedJoin.getClass().getMethod("join", myClass); // path = (Path) join.invoke(embeddedJoin, ((PluralAttributePath) path).getAttribute()); // } catch (Exception e) { // throw new RuntimeException(e); // } } } return path; }