private <X> void registerAttributes(Class metamodelClass, AbstractManagedType<X> managedType) { if (!processedMetamodelClasses.add(metamodelClass)) { return; } // push the attributes on to the metamodel class... for (Attribute<X, ?> attribute : managedType.getDeclaredAttributes()) { registerAttribute(metamodelClass, attribute); } if (IdentifiableType.class.isInstance(managedType)) { final AbstractIdentifiableType<X> entityType = (AbstractIdentifiableType<X>) managedType; // handle version if (entityType.hasDeclaredVersionAttribute()) { registerAttribute(metamodelClass, entityType.getDeclaredVersion()); } // handle id-class mappings specially if (entityType.hasIdClass()) { final Set<SingularAttribute<? super X, ?>> attributes = entityType.getIdClassAttributesSafely(); if (attributes != null) { for (SingularAttribute<? super X, ?> attribute : attributes) { registerAttribute(metamodelClass, attribute); } } } } }
/** * Build a normal attribute. * * @param ownerType The descriptor of the attribute owner (aka declarer). * @param property The Hibernate property descriptor for the attribute * @param <X> The type of the owner * @param <Y> The attribute type * @return The built attribute descriptor or null if the attribute is not part of the JPA 2 model * (eg backrefs) */ @SuppressWarnings({"unchecked"}) public <X, Y> AttributeImplementor<X, Y> buildAttribute( AbstractManagedType<X> ownerType, Property property) { if (property.isSynthetic()) { // hide synthetic/virtual properties (fabricated by Hibernate) from the JPA metamodel. LOG.tracef( "Skipping synthetic property %s(%s)", ownerType.getJavaType().getName(), property.getName()); return null; } LOG.trace( "Building attribute [" + ownerType.getJavaType().getName() + "." + property.getName() + "]"); final AttributeContext<X> attributeContext = wrap(ownerType, property); final AttributeMetadata<X, Y> attributeMetadata = determineAttributeMetadata(attributeContext, NORMAL_MEMBER_RESOLVER); if (attributeMetadata == null) { return null; } if (attributeMetadata.isPlural()) { return buildPluralAttribute((PluralAttributeMetadata) attributeMetadata); } final SingularAttributeMetadata<X, Y> singularAttributeMetadata = (SingularAttributeMetadata<X, Y>) attributeMetadata; final Type<Y> metaModelType = getMetaModelType(singularAttributeMetadata.getValueContext()); return new SingularAttributeImpl<X, Y>( attributeMetadata.getName(), attributeMetadata.getJavaType(), ownerType, attributeMetadata.getMember(), false, false, property.isOptional(), metaModelType, attributeMetadata.getPersistentAttributeType()); }
/** {@inheritDoc} */ public Member resolveMember(AttributeContext attributeContext) { final AbstractManagedType ownerType = attributeContext.getOwnerType(); final Property property = attributeContext.getPropertyMapping(); final Type.PersistenceType persistenceType = ownerType.getPersistenceType(); if (Type.PersistenceType.EMBEDDABLE == persistenceType) { return EMBEDDED_MEMBER_RESOLVER.resolveMember(attributeContext); } else if (Type.PersistenceType.ENTITY == persistenceType || Type.PersistenceType.MAPPED_SUPERCLASS == persistenceType) { final IdentifiableType identifiableType = (IdentifiableType) ownerType; final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel(identifiableType); final String propertyName = property.getName(); final Integer index = entityMetamodel.getPropertyIndexOrNull(propertyName); if (index == null) { // just like in #determineIdentifierJavaMember , this *should* indicate we have an // IdClass mapping return VIRTUAL_IDENTIFIER_MEMBER_RESOLVER.resolveMember(attributeContext); } else { return entityMetamodel.getTuplizer().getGetter(index).getMember(); } } else { throw new IllegalArgumentException("Unexpected owner type : " + persistenceType); } }
private <X> void populateStaticMetamodel(AbstractManagedType<X> managedType) { final Class<X> managedTypeClass = managedType.getJavaType(); if (managedTypeClass == null) { // should indicate MAP entity mode, skip... return; } final String metamodelClassName = managedTypeClass.getName() + "_"; try { final Class metamodelClass = Class.forName(metamodelClassName, true, managedTypeClass.getClassLoader()); // we found the class; so populate it... registerAttributes(metamodelClass, managedType); } catch (ClassNotFoundException ignore) { // nothing to do... } // todo : this does not account for @MappeSuperclass, mainly because this is not being tracked // in our // internal metamodel as populated from the annotatios properly AbstractManagedType<? super X> superType = managedType.getSupertype(); if (superType != null) { populateStaticMetamodel(superType); } }