private FilterSource[] determineFilterSources(PluralAssociationAttribute associationAttribute) { AnnotationInstance filtersAnnotation = JandexHelper.getSingleAnnotation( associationAttribute.annotations(), HibernateDotNames.FILTERS); List<FilterSource> filterSourceList = new ArrayList<FilterSource>(); if (filtersAnnotation != null) { AnnotationInstance[] annotationInstances = filtersAnnotation.value().asNestedArray(); for (AnnotationInstance filterAnnotation : annotationInstances) { FilterSource filterSource = new FilterSourceImpl(filterAnnotation, entityClass.getLocalBindingContext()); filterSourceList.add(filterSource); } } AnnotationInstance filterAnnotation = JandexHelper.getSingleAnnotation( associationAttribute.annotations(), HibernateDotNames.FILTER); if (filterAnnotation != null) { FilterSource filterSource = new FilterSourceImpl(filterAnnotation, entityClass.getLocalBindingContext()); filterSourceList.add(filterSource); } if (filterSourceList.isEmpty()) { return null; } else { return filterSourceList.toArray(new FilterSource[filterSourceList.size()]); } }
@Override public FetchTiming getFetchTiming() { if (associationAttribute.isExtraLazy()) { return FetchTiming.EXTRA_LAZY; } else if (associationAttribute.isLazy()) { return FetchTiming.DELAYED; } else { return FetchTiming.IMMEDIATE; } }
@Override public boolean usesJoinTable() { if (associationAttribute.getMappedBy() != null) { throw new IllegalStateException( "Cannot determine if a join table is used because plural attribute is not the owner."); } // By default, a unidirectional one-to-many (i.e., with mappedBy == null) uses a join table, // unless it has join columns defined. return associationAttribute.getJoinTableAnnotation() != null || (associationAttribute.getJoinTableAnnotation() == null && associationAttribute.getJoinColumnValues().size() == 0); }
@Override public TableSpecificationSource getCollectionTableSpecificationSource() { // todo - see org.hibernate.metamodel.internal.Binder#bindOneToManyCollectionKey // todo - needs to cater for @CollectionTable and @JoinTable if (associationAttribute.getMappedBy() != null) { throw new IllegalStateException( "Cannot get collection table because this association is not the owner."); } final AnnotationInstance joinTableAnnotation = associationAttribute.getJoinTableAnnotation(); return joinTableAnnotation == null ? null : new TableSourceImpl(joinTableAnnotation, entityClass.getLocalBindingContext()); }
private static PluralAttributeElementSource determineElementSource( AttributeSource ownerAttributeSource, PluralAttributeSourceImpl pluralAttributeSource, ConfiguredClass entityClass, String relativePath) { if (ownerAttributeSource == null) { throw new AssertionFailure("ownerAssociationSource must be non-null."); } final PluralAssociationAttribute associationAttribute = pluralAttributeSource.pluralAssociationAttribute(); switch (pluralAttributeSource.pluralAssociationAttribute().getNature()) { case MANY_TO_MANY: return associationAttribute.getMappedBy() == null ? new ManyToManyPluralAttributeElementSourceImpl( pluralAttributeSource, relativePath, entityClass.getLocalBindingContext()) : new ManyToManyMappedByPluralAttributeElementSourceImpl( pluralAttributeSource, relativePath); case MANY_TO_ANY: return new ManyToAnyPluralAttributeElementSourceImpl(pluralAttributeSource, relativePath); case ONE_TO_MANY: boolean usesJoinTable = ownerAttributeSource.isSingular() ? ((ToOneAttributeSource) ownerAttributeSource).getContainingTableName() != null : ((PluralAttributeSource) ownerAttributeSource).usesJoinTable(); if (usesJoinTable) { return associationAttribute.getMappedBy() == null ? new ManyToManyPluralAttributeElementSourceImpl( pluralAttributeSource, relativePath, entityClass.getLocalBindingContext()) : new ManyToManyMappedByPluralAttributeElementSourceImpl( pluralAttributeSource, relativePath); } else { return associationAttribute.getMappedBy() == null ? new OneToManyPluralAttributeElementSourceImpl(pluralAttributeSource, relativePath) : new OneToManyMappedByPluralAttributeElementSourceImpl( pluralAttributeSource, relativePath); } case ELEMENT_COLLECTION_BASIC: return new BasicPluralAttributeElementSourceImpl( associationAttribute, entityClass, relativePath); case ELEMENT_COLLECTION_EMBEDDABLE: { // TODO: cascadeStyles? return new CompositePluralAttributeElementSourceImpl( associationAttribute, entityClass, relativePath); } } throw new AssertionError( "Unexpected attribute nature for a association:" + associationAttribute.getNature()); }
private static List<RelationalValueSource> createRelationalValueSources( PluralAssociationAttribute attribute) { AnnotationInstance columnAnnotation = JandexHelper.getSingleAnnotation(attribute.annotations(), HibernateDotNames.INDEX_COLUMN); if (columnAnnotation == null) { columnAnnotation = JandexHelper.getSingleAnnotation(attribute.annotations(), JPADotNames.ORDER_COLUMN); } if (columnAnnotation == null) { columnAnnotation = JandexHelper.getSingleAnnotation(attribute.annotations(), JPADotNames.MAP_KEY_COLUMN); } Column indexColumn = new Column(columnAnnotation); return Collections.singletonList((RelationalValueSource) new ColumnSourceImpl(indexColumn)); }
@Override public ValueHolder<Class<?>> getElementClassReference() { // needed for arrays Class<?> attributeType = associationAttribute.getAttributeType(); if (attributeType.isArray()) { return new ValueHolder<Class<?>>(attributeType.getComponentType()); } else { return null; } }
public PluralAttributeSourceImpl( final PluralAssociationAttribute associationAttribute, final ConfiguredClass entityClass, final String relativePath) { this.associationAttribute = associationAttribute; this.entityClass = entityClass; this.keySource = new PluralAttributeKeySourceImpl(associationAttribute); this.typeSource = new HibernateTypeSourceImpl(associationAttribute); this.nature = associationAttribute.getPluralAttributeNature(); this.attributePath = StringHelper.isEmpty(relativePath) ? associationAttribute.getName() : relativePath + "." + associationAttribute.getName(); if (associationAttribute.getMappedBy() == null) { this.ownerAttributeSource = this; this.elementSource = determineElementSource(this, this, entityClass, attributePath); } this.filterSources = determineFilterSources(associationAttribute); }
@Override public PluralAttributeElementSource resolvePluralAttributeElementSource( AttributeSourceResolutionContext context) { if (elementSource == null) { // elementSource has not been initialized, so we need to resolve it using the // association owner. // Get the owner attribute source that maps the opposite side of the association. ownerAttributeSource = context.resolveAttributeSource( associationAttribute.getReferencedEntityType(), associationAttribute.getMappedBy()); // Initialize resolved entitySource. elementSource = determineElementSource( ownerAttributeSource, this, entityClass, ""); // TODO not sure what relativePath should be here if (!MappedByAssociationSource.class.isInstance(elementSource)) { throw new AssertionFailure("expected a mappedBy association."); } final AssociationSource ownerAssociationSource; if (ownerAttributeSource.isSingular()) { ownerAssociationSource = (ToOneAttributeSource) ownerAttributeSource; } else { final PluralAttributeSource pluralAttributeSource = (PluralAttributeSource) ownerAttributeSource; if (!AssociationSource.class.isInstance(pluralAttributeSource.getElementSource())) { throw new AssertionFailure("Owner is not an association."); } ownerAssociationSource = (AssociationSource) pluralAttributeSource.getElementSource(); } ownerAssociationSource.addMappedByAssociationSource( (MappedByAssociationSource) elementSource); } return elementSource; }
@Override public boolean isSorted() { return associationAttribute.isSorted(); }
@Override public String getComparatorName() { return associationAttribute.getComparatorName(); }
@Override public boolean isMutable() { return associationAttribute.isMutable(); }
@Override public String getOrder() { return elementSource.getNature() == PluralAttributeElementSource.Nature.MANY_TO_MANY ? null : associationAttribute.getOrderBy(); }
@Override public Caching getCaching() { return associationAttribute.getCaching(); }
@Override public CustomSQL getCustomSqlDeleteAll() { return associationAttribute.getCustomDeleteAll(); }
@Override public int getBatchSize() { return associationAttribute.getBatchSize(); }
@Override public CustomSQL getCustomSqlInsert() { return associationAttribute.getCustomInsert(); }
@Override public String getCustomLoaderName() { return associationAttribute.getCustomLoaderName(); }
@Override public String getMappedBy() { return associationAttribute.getMappedBy(); }
@Override public String getWhere() { return associationAttribute.getWhereClause(); }
@Override public String getCustomPersisterClassName() { return associationAttribute.getCustomPersister(); }
@Override public FetchStyle getFetchStyle() { return associationAttribute.getFetchStyle(); }
@Override public String getPropertyAccessorName() { return associationAttribute.getAccessType(); }
@Override public boolean isIncludedInOptimisticLocking() { return associationAttribute.isOptimisticLockable(); }
@Override public CustomSQL getCustomSqlUpdate() { return associationAttribute.getCustomUpdate(); }
@Override public String getCollectionTableCheck() { return associationAttribute.getCheckCondition(); }