static Object makeCaller ( Object tpl, Object getters ) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, Exception, ClassNotFoundException { PojoComponentTuplizer tup = Reflections.createWithoutConstructor(PojoComponentTuplizer.class); Reflections.getField(AbstractComponentTuplizer.class, "getters").set(tup, getters); ComponentType t = Reflections.createWithConstructor(ComponentType.class, AbstractType.class, new Class[0], new Object[0]); Reflections.setFieldValue(t, "componentTuplizer", tup); Reflections.setFieldValue(t, "propertySpan", 1); Reflections.setFieldValue(t, "propertyTypes", new Type[] { t }); TypedValue v1 = new TypedValue(t, null); Reflections.setFieldValue(v1, "value", tpl); Reflections.setFieldValue(v1, "type", t); TypedValue v2 = new TypedValue(t, null); Reflections.setFieldValue(v2, "value", tpl); Reflections.setFieldValue(v2, "type", t); return Gadgets.makeMap(v1, v2); }
/** * Extract a component property value. * * @param type The component property types. * @param component The component instance itself. * @param propertyPath The property path for the property to be extracted. * @return The property value extracted. */ protected Object getComponentValue(ComponentType type, Object component, String propertyPath) { final int loc = propertyPath.indexOf( '.' ); final String basePropertyName = loc > 0 ? propertyPath.substring( 0, loc ) : propertyPath; final int index = findSubPropertyIndex( type, basePropertyName ); final Object baseValue = type.getPropertyValue( component, index ); if ( loc > 0 ) { if ( baseValue == null ) { return null; } return getComponentValue( (ComponentType) type.getSubtypes()[index], baseValue, propertyPath.substring(loc+1) ); } else { return baseValue; } }
@Override public boolean needsRecreate(CollectionPersister persister) { // Workaround for situations like HHH-7072. If the collection element is a component that consists entirely // of nullable properties, we currently have to forcefully recreate the entire collection. See the use // of hasNotNullableColumns in the AbstractCollectionPersister constructor for more info. In order to delete // row-by-row, that would require SQL like "WHERE ( COL = ? OR ( COL is null AND ? is null ) )", rather than // the current "WHERE COL = ?" (fails for null for most DBs). Note that // the param would have to be bound twice. Until we eventually add "parameter bind points" concepts to the // AST in ORM 5+, handling this type of condition is either extremely difficult or impossible. Forcing // recreation isn't ideal, but not really any other option in ORM 4. if (persister.getElementType() instanceof ComponentType) { ComponentType componentType = (ComponentType) persister.getElementType(); return !componentType.hasNotNullProperty(); } return false; }
public ComponentJoin( FromClause fromClause, FromElement origin, String alias, String componentPath, ComponentType componentType) { super( fromClause, origin, alias ); this.componentPath = componentPath; this.componentType = componentType; this.componentProperty = StringHelper.unqualify( componentPath ); fromClause.addJoinByPathMap( componentPath, this ); initializeComponentJoin( new ComponentFromElementType( this ) ); this.columns = origin.getPropertyMapping( "" ).toColumns( getTableAlias(), componentProperty ); StringBuilder buf = new StringBuilder(); for ( int j = 0; j < columns.length; j++ ) { final String column = columns[j]; if ( j > 0 ) { buf.append( ", " ); } buf.append( column ); } this.columnsFragment = buf.toString(); }
public Object getPropertyValue(Object entity, String propertyPath) throws HibernateException { int loc = propertyPath.indexOf('.'); String basePropertyName = loc>0 ? propertyPath.substring(0, loc) : propertyPath; int index = entityMetamodel.getPropertyIndex( basePropertyName ); Object baseValue = getPropertyValue( entity, index ); if ( loc>0 ) { ComponentType type = (ComponentType) entityMetamodel.getPropertyTypes()[index]; return getComponentValue( type, baseValue, propertyPath.substring(loc+1) ); } else { return baseValue; } }
public void testComponentQueries() { Session s = openSession(); s.beginTransaction(); Type[] types = s.createQuery( "select h.name from Human h" ).getReturnTypes(); assertEquals( 1, types.length ); assertTrue( types[0] instanceof ComponentType ); // Test the ability to perform comparisions between component values s.createQuery( "from Human h where h.name = h.name" ).list(); s.createQuery( "from Human h where h.name = :name" ).setParameter( "name", new Name() ).list(); s.createQuery( "from Human where name = :name" ).setParameter( "name", new Name() ).list(); s.createQuery( "from Human h where :name = h.name" ).setParameter( "name", new Name() ).list(); s.createQuery( "from Human h where :name <> h.name" ).setParameter( "name", new Name() ).list(); // Test the ability to perform comparisions between a component and an explicit row-value s.createQuery( "from Human h where h.name = ('John', 'X', 'Doe')" ).list(); s.createQuery( "from Human h where ('John', 'X', 'Doe') = h.name" ).list(); s.createQuery( "from Human h where ('John', 'X', 'Doe') <> h.name" ).list(); s.createQuery( "from Human h where ('John', 'X', 'Doe') >= h.name" ).list(); s.createQuery( "from Human h order by h.name" ).list(); s.getTransaction().commit(); s.close(); }
/** * Get the value of the foreign key property. This comes from the entity, but if that value is * null, and the entity is deleted, we try to get it from the originalValuesMap. * @param entityInfo Breeze EntityInfo * @param meta Metadata for the entity class * @param foreignKeyName Name of the foreign key property of the entity, e.g. "CustomerID" * @return */ private Object getForeignKeyValue(EntityInfo entityInfo, ClassMetadata meta, String foreignKeyName) { Object entity = entityInfo.entity; Object id = null; if (foreignKeyName.equalsIgnoreCase(meta.getIdentifierPropertyName())) { id = meta.getIdentifier(entity, null); } else if (Arrays.asList(meta.getPropertyNames()).contains(foreignKeyName)) { id = meta.getPropertyValue(entity, foreignKeyName); } else if (meta.getIdentifierType().isComponentType()) { // compound key ComponentType compType = (ComponentType) meta.getIdentifierType(); int index = Arrays.asList(compType.getPropertyNames()).indexOf(foreignKeyName); if (index >= 0) { Object idComp = meta.getIdentifier(entity, null); id = compType.getPropertyValue(idComp, index, EntityMode.POJO); } } if (id == null && entityInfo.entityState == EntityState.Deleted) { id = entityInfo.originalValuesMap.get(foreignKeyName); } return id; }
/** * This is an HbnContainer specific utility method that is used to retrieve the list of embedded property key * identifiers. */ protected Collection<String> getEmbeddedKeyPropertyIds() { logger.executionTrace(); final ArrayList<String> embeddedKeyPropertyIds = new ArrayList<String>(); final Type identifierType = classMetadata.getIdentifierType(); if (identifierType.isComponentType()) { final ComponentType idComponent = (ComponentType) identifierType; final String[] propertyNameArray = idComponent.getPropertyNames(); if (propertyNameArray != null) { final List<String> propertyNames = Arrays.asList(propertyNameArray); embeddedKeyPropertyIds.addAll(propertyNames); } } return embeddedKeyPropertyIds; }
/** * This is an internal HbnContainer utility method. Determines if a property is contained within an embedded key. */ protected boolean propertyInEmbeddedKey(Object propertyId) { logger.executionTrace(); if (embeddedPropertiesCache.containsKey(propertyId)) return embeddedPropertiesCache.get(propertyId); final Type identifierType = classMetadata.getIdentifierType(); if (identifierType.isComponentType()) { final ComponentType componentType = (ComponentType) identifierType; final String[] idPropertyNames = componentType.getPropertyNames(); final List<String> idPropertyNameList = Arrays.asList(idPropertyNames); return idPropertyNameList.contains(propertyId); } return false; }
/** * Private helper method to construct component ids with an optional alias. * * @param sb * a {@link StringBuffer} * @param componentType * the {@link ComponentType} * @param criteriaQuery * the {@link CriteriaQuery} * @param criteria * the {@link Criteria} * @param position * the position of the alias, appened if >= 0 */ private void appendComponentIds(final StringBuffer sb, final ComponentType componentType, final CriteriaQuery criteriaQuery, final Criteria criteria, final Integer position) { final String[] idProperties = componentType.getPropertyNames(); int currPos = position != null ? position.intValue() : -1; for (int i = 0; i < idProperties.length; i++) { sb.append(criteriaQuery.getColumn(criteria, groupByProperty + "." + idProperties[i])); if (currPos >= 0) { sb.append(" as y").append(currPos).append('_'); currPos++; } if (i + 1 < idProperties.length) { sb.append(", "); } } }
ComponentCollectionCriteriaInfoProvider(QueryableCollection persister) { this.persister = persister; if ( !persister.getElementType().isComponentType() ) { throw new IllegalArgumentException( "persister for role " + persister.getRole() + " is not a collection-of-component" ); } ComponentType componentType = (ComponentType) persister.getElementType(); String[] names = componentType.getPropertyNames(); Type[] types = componentType.getSubtypes(); for ( int i = 0; i < names.length; i++ ) { subTypes.put( names[i], types[i] ); } }
@Override public Object readRow(ResultSet resultSet, ResultSetProcessingContextImpl context) throws SQLException { final ResultSetProcessingContext.EntityReferenceProcessingState processingState = rootReturnReader.getIdentifierResolutionContext( context ); // if the entity reference we are hydrating is a Return, it is possible that its EntityKey is // supplied by the QueryParameter optional entity information if ( context.shouldUseOptionalEntityInformation() && context.getQueryParameters().getOptionalId() != null ) { EntityKey entityKey = ResultSetProcessorHelper.getOptionalObjectKey( context.getQueryParameters(), context.getSession() ); processingState.registerIdentifierHydratedForm( entityKey.getIdentifier() ); processingState.registerEntityKey( entityKey ); final EntityPersister entityPersister = processingState.getEntityReference().getEntityPersister(); if ( entityPersister.getIdentifierType().isComponentType() ) { final ComponentType identifierType = (ComponentType) entityPersister.getIdentifierType(); if ( !identifierType.isEmbedded() ) { addKeyManyToOnesToSession( context, identifierType, entityKey.getIdentifier() ); } } } return super.readRow( resultSet, context ); }
private void addKeyManyToOnesToSession(ResultSetProcessingContextImpl context, ComponentType componentType, Object component ) { for ( int i = 0 ; i < componentType.getSubtypes().length ; i++ ) { final Type subType = componentType.getSubtypes()[ i ]; final Object subValue = componentType.getPropertyValue( component, i, context.getSession() ); if ( subType.isEntityType() ) { ( (Session) context.getSession() ).buildLockRequest( LockOptions.NONE ).lock( subValue ); } else if ( subType.isComponentType() ) { addKeyManyToOnesToSession( context, (ComponentType) subType, subValue ); } } }
private static MappedIdentifierValueMarshaller buildMappedIdentifierValueMarshaller( ComponentType mappedIdClassComponentType, ComponentType virtualIdComponent) { // so basically at this point we know we have a "mapped" composite identifier // which is an awful way to say that the identifier is represented differently // in the entity and in the identifier value. The incoming value should // be an instance of the mapped identifier class (@IdClass) while the incoming entity // should be an instance of the entity class as defined by metamodel. // // However, even within that we have 2 potential scenarios: // 1) @IdClass types and entity @Id property types match // - return a NormalMappedIdentifierValueMarshaller // 2) They do not match // - return a IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller boolean wereAllEquivalent = true; // the sizes being off is a much bigger problem that should have been caught already... for ( int i = 0; i < virtualIdComponent.getSubtypes().length; i++ ) { if ( virtualIdComponent.getSubtypes()[i].isEntityType() && ! mappedIdClassComponentType.getSubtypes()[i].isEntityType() ) { wereAllEquivalent = false; break; } } return wereAllEquivalent ? new NormalMappedIdentifierValueMarshaller( virtualIdComponent, mappedIdClassComponentType ) : new IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller( virtualIdComponent, mappedIdClassComponentType ); }
private IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller(ComponentType virtualIdComponent, ComponentType mappedIdentifierType) { this.virtualIdComponent = virtualIdComponent; this.mappedIdentifierType = mappedIdentifierType; }
@Override public Object getPropertyValue(Object entity, String propertyPath) throws HibernateException { int loc = propertyPath.indexOf('.'); String basePropertyName = loc > 0 ? propertyPath.substring( 0, loc ) : propertyPath; //final int index = entityMetamodel.getPropertyIndexOrNull( basePropertyName ); Integer index = entityMetamodel.getPropertyIndexOrNull( basePropertyName ); if (index == null) { propertyPath = PropertyPath.IDENTIFIER_MAPPER_PROPERTY + "." + propertyPath; loc = propertyPath.indexOf('.'); basePropertyName = loc > 0 ? propertyPath.substring( 0, loc ) : propertyPath; } index = entityMetamodel.getPropertyIndexOrNull( basePropertyName ); final Object baseValue = getPropertyValue( entity, index ); if ( loc > 0 ) { if ( baseValue == null ) { return null; } return getComponentValue( (ComponentType) entityMetamodel.getPropertyTypes()[index], baseValue, propertyPath.substring(loc+1) ); } else { return baseValue; } }
private int findSubPropertyIndex(ComponentType type, String subPropertyName) { final String[] propertyNames = type.getPropertyNames(); for ( int index = 0; index<propertyNames.length; index++ ) { if ( subPropertyName.equals( propertyNames[index] ) ) { return index; } } throw new MappingException( "component property not found: " + subPropertyName ); }
public FromElement createComponentJoin(ComponentType type) { // need to create a "place holder" from-element that can store the component/alias for this // component join return new ComponentJoin( fromClause, origin, classAlias, path, type ); }
private static void killUnwantedAssociationValues(String[] propertyNames, Type[] propertyTypes, Object[] values, int depth) { if (values == null) { return; } for (int i = 0; i < propertyTypes.length; i++) { String name = propertyNames[i]; Type type = propertyTypes[i]; Object value = values[i]; if (LOGGER.isTraceEnabled()) { LOGGER.trace("{}- killUnwantedAssociationValues processing #{}: {} (type={}, value={})", StringUtils.repeat(" ", depth), i, name, type, value); } if (type instanceof ComponentType) { ComponentType componentType = (ComponentType) type; killUnwantedAssociationValues(componentType.getPropertyNames(), componentType.getSubtypes(), (Object[]) value, depth+1); } else if (type instanceof ManyToOneType) { if (ASSOCIATION_TO_REMOVE.equals(name)) { if (LOGGER.isTraceEnabled()) { LOGGER.trace("{}- killUnwantedAssociationValues KILLED #{}: {} (type={}, value={})", StringUtils.repeat(" ", depth), i, name, type, value); } values[i] = null; } } } }
private Type buildType() { // TODO : temporary initial step towards HHH-1907 ComponentMetamodel metamodel = new ComponentMetamodel( this ); if ( isEmbedded() ) { return new EmbeddedComponentType( metamodel ); } else { return new ComponentType( metamodel ); } }
public Serializable getIdentifier(Object entity) throws HibernateException { final Object id; if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) { id = entity; } else { if ( idGetter == null ) { if (identifierMapperType==null) { throw new HibernateException( "The class has no identifier property: " + getEntityName() ); } else { ComponentType copier = (ComponentType) entityMetamodel.getIdentifierProperty().getType(); id = copier.instantiate( getEntityMode() ); copier.setPropertyValues( id, identifierMapperType.getPropertyValues( entity, getEntityMode() ), getEntityMode() ); } } else { id = idGetter.get( entity ); } } try { return (Serializable) id; } catch ( ClassCastException cce ) { StringBuffer msg = new StringBuffer( "Identifier classes must be serializable. " ); if ( id != null ) { msg.append( id.getClass().getName() + " is not serializable. " ); } if ( cce.getMessage() != null ) { msg.append( cce.getMessage() ); } throw new ClassCastException( msg.toString() ); } }
/** * Extract a component property value. * * @param type The component property types. * @param component The component instance itself. * @param propertyPath The property path for the property to be extracted. * @return The property value extracted. */ protected Object getComponentValue(ComponentType type, Object component, String propertyPath) { int loc = propertyPath.indexOf('.'); String basePropertyName = loc>0 ? propertyPath.substring(0, loc) : propertyPath; String[] propertyNames = type.getPropertyNames(); int index=0; for ( ; index<propertyNames.length; index++ ) { if ( basePropertyName.equals( propertyNames[index] ) ) break; } if (index==propertyNames.length) { throw new MappingException( "component property not found: " + basePropertyName ); } Object baseValue = type.getPropertyValue( component, index, getEntityMode() ); if ( loc>0 ) { ComponentType subtype = (ComponentType) type.getSubtypes()[index]; return getComponentValue( subtype, baseValue, propertyPath.substring(loc+1) ); } else { return baseValue; } }
/** * Handle a specific property if it is a Association or Component relationship. * @param propName * @param propType * @param entityInfo * @param meta */ private void processRelationship(String propName, Type propType, EntityInfo entityInfo, ClassMetadata meta) { if (propType.isAssociationType() && propType.isEntityType()) { fixupRelationship(propName, (EntityType) propType, entityInfo, meta); } else if (propType.isComponentType()) { fixupComponentRelationships(propName, (ComponentType) propType, entityInfo, meta); } }
/** * Connect the related entities based on the foreign key values found in a component type. * This updates the values of the component's properties. * @param propName Name of the (component) property of the entity. May be null if the property is the entity's identifier. * @param compType Type of the component * @param entityInfo Breeze EntityInfo * @param meta Metadata for the entity class */ private void fixupComponentRelationships(String propName, ComponentType compType, EntityInfo entityInfo, ClassMetadata meta) { String[] compPropNames = compType.getPropertyNames(); Type[] compPropTypes = compType.getSubtypes(); Object component = null; Object[] compValues = null; boolean isChanged = false; for (int j = 0; j < compPropNames.length; j++) { Type compPropType = compPropTypes[j]; if (compPropType.isAssociationType() && compPropType.isEntityType()) { if (compValues == null) { // get the value of the component's subproperties component = getPropertyValue(meta, entityInfo.entity, propName); compValues = compType.getPropertyValues(component, EntityMode.POJO); } if (compValues[j] == null) { // the related entity is null Object relatedEntity = getRelatedEntity(compPropNames[j], (EntityType) compPropType, entityInfo, meta); if (relatedEntity != null) { compValues[j] = relatedEntity; isChanged = true; } } else if (removeMode) { // remove the relationship compValues[j] = null; isChanged = true; } } } if (isChanged) { compType.setPropertyValues(component, compValues, EntityMode.POJO); } }
/** * Gets the data type of all Properties identified by the given Property ID. This method does pretty much the same * thing as EntityItemProperty#getType() */ public Class<?> getType(Object propertyId) { logger.executionTrace(); // TODO: refactor to use same code as EntityItemProperty#getType() // This will also fix incomplete implementation of this method (for association types). Not critical as // Components don't really rely on this methods. if (addedProperties.keySet().contains(propertyId)) return addedProperties.get(propertyId); if (propertyInEmbeddedKey(propertyId)) { final ComponentType idType = (ComponentType) classMetadata.getIdentifierType(); final String[] propertyNames = idType.getPropertyNames(); for (int i = 0; i < propertyNames.length; i++) { String name = propertyNames[i]; if (name.equals(propertyId)) { String idName = classMetadata.getIdentifierPropertyName(); try { Field idField = entityType.getDeclaredField(idName); Field propertyField = idField.getType().getDeclaredField((String) propertyId); return propertyField.getType(); } catch (NoSuchFieldException ex) { throw new RuntimeException("Could not find the type of specified container property.", ex); } } } } Type propertyType = classMetadata.getPropertyType(propertyId.toString()); return propertyType.getReturnedClass(); }
@Override public String toSqlString(final Criteria criteria, final int position, final CriteriaQuery criteriaQuery) throws HibernateException { final Type identifierType = criteriaQuery.getIdentifierType(criteria); if (identifierType.isComponentType()) { final StringBuffer sb = new StringBuffer(); appendComponentIds(sb, (ComponentType) identifierType, criteriaQuery, criteria, new Integer(position)); return sb.toString(); } return super.toSqlString(criteria, position, criteriaQuery); }
@Override public String toGroupSqlString(final Criteria criteria, final CriteriaQuery criteriaQuery) throws HibernateException { final StringBuffer sb = new StringBuffer(50); final Type identifierType = criteriaQuery.getIdentifierType(criteria); if (identifierType.isComponentType()) { appendComponentIds(sb, (ComponentType) identifierType, criteriaQuery, criteria, null); } else { sb.append(criteriaQuery.getColumn(criteria, groupByProperty)); } // Append HAVING clause sb.append(" having "); sb.append("("); // Remove the alias final String proj = projection.toSqlString(criteria, 0xCAFEBABE, criteriaQuery); sb.append(proj.substring(0, proj.indexOf("as")).trim()); sb.append(")"); sb.append(SPACE_STRING) .append(op.getSqloperator()) .append(SPACE_STRING) .append(value); return sb.toString(); }
/** * @deprecated This method does not work well due to Hibernate bug HHH-817, nor does * AliasToBeanResultTransformer handle multi-level property values. * Therefore it should not be used. * @see http://opensource.atlassian.com/projects/hibernate/browse/HHH-817 */ @Deprecated public static Projection createProjectionList(final String identifierProperty, final Type identifierType, final String[] propertyNames, final Class<?> domainClass) { final ProjectionList projectionList = Projections.projectionList(); if (identifierType.isComponentType()) { final String[] idProperties = ((ComponentType) (identifierType)) .getPropertyNames(); for (final String idProperty : idProperties) { final String idPath = identifierProperty + "." + idProperty; projectionList.add(Projections.property(idPath)); } } else { projectionList.add(Projections.id()); } for (final String propertyName : propertyNames) { final Field field = ReflectionUtils.findField(domainClass, propertyName); if (!hasAssociationAnnotation(field)) { projectionList.add(Projections.property(propertyName), propertyName); } } return projectionList; }
private NormalMappedIdentifierValueMarshaller(ComponentType virtualIdComponent, ComponentType mappedIdentifierType) { this.virtualIdComponent = virtualIdComponent; this.mappedIdentifierType = mappedIdentifierType; }
public ComponentType getComponentType() { return componentType; }
/** * This method gets the value that is stored by the property. The returned object is compatible with the * class returned by getType(). */ @SuppressWarnings("unchecked") @Override public Object getValue() { logger.executionTrace(); final Session session = sessionFactory.getCurrentSession(); final SessionImplementor sessionImplementor = (SessionImplementor) session; if (!sessionFactory.getCurrentSession().contains(pojo)) pojo = (T) session.get(entityType, (Serializable) getIdForPojo(pojo)); if (propertyInEmbeddedKey(propertyName)) { final ComponentType identifierType = (ComponentType) classMetadata.getIdentifierType(); final String[] propertyNames = identifierType.getPropertyNames(); for (int i = 0; i < propertyNames.length; i++) { String name = propertyNames[i]; if (name.equals(propertyName)) { final Object id = classMetadata.getIdentifier(pojo, sessionImplementor); return identifierType.getPropertyValue(id, i, EntityMode.POJO); } } } final Type propertyType = getPropertyType(); final Object propertyValue = classMetadata.getPropertyValue(pojo, propertyName); if (!propertyType.isAssociationType()) return propertyValue; if (propertyType.isCollectionType()) { if (propertyValue == null) return null; final HashSet<Serializable> identifiers = new HashSet<Serializable>(); final Collection<?> pojos = (Collection<?>) propertyValue; for (Object object : pojos) { if (!session.contains(object)) object = session.merge(object); identifiers.add(session.getIdentifier(object)); } return identifiers; } if (propertyValue == null) return null; final Class<?> propertyTypeClass = propertyType.getReturnedClass(); final ClassMetadata metadata = sessionFactory.getClassMetadata(propertyTypeClass); final Serializable identifier = metadata.getIdentifier(propertyValue, sessionImplementor); return identifier; }
/** * Returns the type of the Property. The methods getValue and setValue must be compatible with this type: * one must be able to safely cast the value returned from getValue to the given type and pass any variable * assignable to this type as an argument to setValue. */ public Class<?> getType() { logger.executionTrace(); if (propertyInEmbeddedKey(propertyName)) { final ComponentType idType = (ComponentType) classMetadata.getIdentifierType(); final String[] propertyNames = idType.getPropertyNames(); for (String name : propertyNames) { if (name.equals(propertyName)) { try { final String identifierName = classMetadata.getIdentifierPropertyName(); final Field identifierField = entityType.getDeclaredField(identifierName); final Field propertyField = identifierField.getType().getDeclaredField(propertyName); return propertyField.getType(); } catch (NoSuchFieldException e) { logger.error(e); throw new RuntimeException("Failed to find the type of the container property.", e); } } } } final Type propertyType = getPropertyType(); if (propertyType.isCollectionType()) { final Class<?> returnedClass = propertyType.getReturnedClass(); return returnedClass; } if (propertyType.isAssociationType()) { // For association the the property value type is the type of referenced types identifier. final ClassMetadata metadata = sessionFactory.getClassMetadata( classMetadata.getPropertyType(propertyName).getReturnedClass()); return metadata.getIdentifierType().getReturnedClass(); } return classMetadata.getPropertyType(propertyName).getReturnedClass(); }
/** * @param request * @return * @see edu.utah.further.core.chain.AbstractRequestHandler#process(edu.utah.further.core.api.chain.ChainRequest) * @see http://opensource.atlassian.com/projects/hibernate/browse/HHH-817 */ @Override public boolean process(final ChainRequest request) { final HibernateExecReq executionReq = new HibernateExecReq(request); // Validate required input final GenericCriteria hibernateCriteria = executionReq.getResult(); notNull(hibernateCriteria, "Expected Hibernate criteria"); final Class<? extends PersistentEntity<?>> domainClass = executionReq .getRootEntity(); final Class<? extends PersistentEntity<?>> entityClass = dao .getEntityClass(domainClass); notNull(entityClass, "Expected root entity class"); final SessionFactory sessionFactory = executionReq.getSessionFactory(); notNull(sessionFactory, "Expected SessionFactory"); final ClassMetadata classMetadata = sessionFactory.getClassMetadata(entityClass); final String identifierName = classMetadata.getIdentifierPropertyName(); final Type identifierType = classMetadata.getIdentifierType(); // A hack to obtain projections out of the critieria by casting to the Hibernate // implementation. TODO: improve adapter to do that via interface access final ProjectionList projectionList = Projections.projectionList(); final Projection existingProjection = ((CriteriaImpl) hibernateCriteria .getHibernateCriteria()).getProjection(); if (existingProjection != null && !overrideExistingProjection) { return false; } if (identifierType.isComponentType()) { final ComponentType componentType = (ComponentType) identifierType; final String[] idPropertyNames = componentType.getPropertyNames(); // Add distinct to the first property projectionList.add( Projections.distinct(Property.forName(identifierName + PROPERTY_SCOPE_CHAR + idPropertyNames[0])), idPropertyNames[0]); // Add the remaining properties to the projection list for (int i = 1; i < idPropertyNames.length; i++) { projectionList.add( Property.forName(identifierName + PROPERTY_SCOPE_CHAR + idPropertyNames[i]), idPropertyNames[i]); } hibernateCriteria.setProjection(projectionList); hibernateCriteria.setResultTransformer(new AliasToBeanResultTransformer( ReflectionUtils.findField(entityClass, identifierName).getType())); } else { // 'this' required to avoid HHH-817 projectionList.add(Projections.distinct(Property.forName(THIS_CONTEXT + identifierName))); hibernateCriteria.setProjection(projectionList); } executionReq.setResult(hibernateCriteria); return false; }
@Override protected void createFromJoinElement( AST path, AST alias, int joinType, AST fetchNode, AST propertyFetch, AST with) throws SemanticException { boolean fetch = fetchNode != null; if ( fetch && isSubQuery() ) { throw new QueryException( "fetch not allowed in subquery from-elements" ); } // The path AST should be a DotNode, and it should have been evaluated already. if ( path.getType() != SqlTokenTypes.DOT ) { throw new SemanticException( "Path expected for join!" ); } DotNode dot = (DotNode) path; JoinType hibernateJoinType = JoinProcessor.toHibernateJoinType( joinType ); dot.setJoinType( hibernateJoinType ); // Tell the dot node about the join type. dot.setFetch( fetch ); // Generate an explicit join for the root dot node. The implied joins will be collected and passed up // to the root dot node. dot.resolve( true, false, alias == null ? null : alias.getText() ); final FromElement fromElement; if ( dot.getDataType() != null && dot.getDataType().isComponentType() ) { if ( dot.getDataType().isAnyType() ) { throw new SemanticException( "An AnyType attribute cannot be join fetched" ); // ^^ because the discriminator (aka, the "meta columns") must be known to the SQL in // a non-parameterized way. } FromElementFactory factory = new FromElementFactory( getCurrentFromClause(), dot.getLhs().getFromElement(), dot.getPropertyPath(), alias == null ? null : alias.getText(), null, false ); fromElement = factory.createComponentJoin( (ComponentType) dot.getDataType() ); } else { fromElement = dot.getImpliedJoin(); fromElement.setAllPropertyFetch( propertyFetch != null ); if ( with != null ) { if ( fetch ) { throw new SemanticException( "with-clause not allowed on fetched associations; use filters" ); } handleWithFragment( fromElement, with ); } } if ( LOG.isDebugEnabled() ) { LOG.debug( "createFromJoinElement() : " + getASTPrinter().showAsString( fromElement, "-- join tree --" ) ); } }