Search in sources :

Example 1 with ElementCollection

use of jakarta.persistence.ElementCollection in project hibernate-orm by hibernate.

the class AnnotationBinder method bindCollection.

private static void bindCollection(PropertyHolder propertyHolder, Nullability nullability, PropertyData inferredData, Map<String, IdentifierGeneratorDefinition> classGenerators, EntityBinder entityBinder, boolean isIdentifierMapper, MetadataBuildingContext context, Map<XClass, InheritanceState> inheritanceStatePerClass, XProperty property, AnnotatedJoinColumn[] joinColumns) {
    OneToMany oneToManyAnn = property.getAnnotation(OneToMany.class);
    ManyToMany manyToManyAnn = property.getAnnotation(ManyToMany.class);
    ElementCollection elementCollectionAnn = property.getAnnotation(ElementCollection.class);
    if ((oneToManyAnn != null || manyToManyAnn != null || elementCollectionAnn != null) && isToManyAssociationWithinEmbeddableCollection(propertyHolder)) {
        throw new AnnotationException("@OneToMany, @ManyToMany or @ElementCollection cannot be used inside an @Embeddable that is also contained within an @ElementCollection: " + BinderHelper.getPath(propertyHolder, inferredData));
    }
    if (property.isAnnotationPresent(OrderColumn.class) && manyToManyAnn != null && !manyToManyAnn.mappedBy().isEmpty()) {
        throw new AnnotationException("Explicit @OrderColumn on inverse side of @ManyToMany is illegal: " + BinderHelper.getPath(propertyHolder, inferredData));
    }
    final IndexColumn indexColumn = IndexColumn.fromAnnotations(property.getAnnotation(OrderColumn.class), property.getAnnotation(org.hibernate.annotations.IndexColumn.class), property.getAnnotation(ListIndexBase.class), propertyHolder, inferredData, entityBinder.getSecondaryTables(), context);
    CollectionBinder collectionBinder = getCollectionBinder(property, hasMapKeyAnnotation(property), context);
    collectionBinder.setIndexColumn(indexColumn);
    collectionBinder.setMapKey(property.getAnnotation(MapKey.class));
    collectionBinder.setPropertyName(inferredData.getPropertyName());
    collectionBinder.setBatchSize(property.getAnnotation(BatchSize.class));
    collectionBinder.setJpaOrderBy(property.getAnnotation(jakarta.persistence.OrderBy.class));
    collectionBinder.setSqlOrderBy(getOverridableAnnotation(property, OrderBy.class, context));
    collectionBinder.setNaturalSort(property.getAnnotation(SortNatural.class));
    collectionBinder.setComparatorSort(property.getAnnotation(SortComparator.class));
    collectionBinder.setCache(property.getAnnotation(Cache.class));
    collectionBinder.setPropertyHolder(propertyHolder);
    Cascade hibernateCascade = property.getAnnotation(Cascade.class);
    NotFound notFound = property.getAnnotation(NotFound.class);
    collectionBinder.setIgnoreNotFound(notFound != null && notFound.action() == NotFoundAction.IGNORE);
    collectionBinder.setCollectionType(inferredData.getProperty().getElementClass());
    collectionBinder.setAccessType(inferredData.getDefaultAccess());
    AnnotatedColumn[] elementColumns;
    // do not use "element" if you are a JPA 2 @ElementCollection, only for legacy Hibernate mappings
    PropertyData virtualProperty = property.isAnnotationPresent(ElementCollection.class) ? inferredData : new WrappedInferredData(inferredData, "element");
    Comment comment = property.getAnnotation(Comment.class);
    if (property.isAnnotationPresent(Column.class)) {
        elementColumns = buildColumnFromAnnotation(property.getAnnotation(Column.class), comment, nullability, propertyHolder, virtualProperty, entityBinder.getSecondaryTables(), context);
    } else if (property.isAnnotationPresent(Formula.class)) {
        elementColumns = buildFormulaFromAnnotation(getOverridableAnnotation(property, Formula.class, context), comment, nullability, propertyHolder, virtualProperty, entityBinder.getSecondaryTables(), context);
    } else if (property.isAnnotationPresent(Columns.class)) {
        elementColumns = buildColumnsFromAnnotations(property.getAnnotation(Columns.class).columns(), comment, nullability, propertyHolder, virtualProperty, entityBinder.getSecondaryTables(), context);
    } else {
        elementColumns = buildColumnFromNoAnnotation(comment, nullability, propertyHolder, virtualProperty, entityBinder.getSecondaryTables(), context);
    }
    JoinColumn[] joinKeyColumns = mapKeyColumns(propertyHolder, inferredData, entityBinder, context, property, collectionBinder, comment);
    AnnotatedJoinColumn[] mapJoinColumns = buildJoinColumnsWithDefaultColumnSuffix(joinKeyColumns, comment, null, entityBinder.getSecondaryTables(), propertyHolder, inferredData.getPropertyName(), "_KEY", context);
    collectionBinder.setMapKeyManyToManyColumns(mapJoinColumns);
    // potential element
    collectionBinder.setEmbedded(property.isAnnotationPresent(Embedded.class));
    collectionBinder.setElementColumns(elementColumns);
    collectionBinder.setProperty(property);
    // TODO enhance exception with @ManyToAny and @CollectionOfElements
    if (oneToManyAnn != null && manyToManyAnn != null) {
        throw new AnnotationException("@OneToMany and @ManyToMany on the same property is not allowed: " + propertyHolder.getEntityName() + "." + inferredData.getPropertyName());
    }
    String mappedBy = null;
    ReflectionManager reflectionManager = context.getBootstrapContext().getReflectionManager();
    if (oneToManyAnn != null) {
        for (AnnotatedJoinColumn column : joinColumns) {
            if (column.isSecondary()) {
                throw new NotYetImplementedException("Collections having FK in secondary table");
            }
        }
        collectionBinder.setFkJoinColumns(joinColumns);
        mappedBy = oneToManyAnn.mappedBy();
        // noinspection unchecked
        collectionBinder.setTargetEntity(reflectionManager.toXClass(oneToManyAnn.targetEntity()));
        collectionBinder.setCascadeStrategy(getCascadeStrategy(oneToManyAnn.cascade(), hibernateCascade, oneToManyAnn.orphanRemoval(), false));
        collectionBinder.setOneToMany(true);
    } else if (elementCollectionAnn != null) {
        for (AnnotatedJoinColumn column : joinColumns) {
            if (column.isSecondary()) {
                throw new NotYetImplementedException("Collections having FK in secondary table");
            }
        }
        collectionBinder.setFkJoinColumns(joinColumns);
        mappedBy = "";
        final Class<?> targetElement = elementCollectionAnn.targetClass();
        collectionBinder.setTargetEntity(reflectionManager.toXClass(targetElement));
        // collectionBinder.setCascadeStrategy( getCascadeStrategy( embeddedCollectionAnn.cascade(), hibernateCascade ) );
        collectionBinder.setOneToMany(true);
    } else if (manyToManyAnn != null) {
        mappedBy = manyToManyAnn.mappedBy();
        // noinspection unchecked
        collectionBinder.setTargetEntity(reflectionManager.toXClass(manyToManyAnn.targetEntity()));
        collectionBinder.setCascadeStrategy(getCascadeStrategy(manyToManyAnn.cascade(), hibernateCascade, false, false));
        collectionBinder.setOneToMany(false);
    } else if (property.isAnnotationPresent(ManyToAny.class)) {
        mappedBy = "";
        collectionBinder.setTargetEntity(reflectionManager.toXClass(void.class));
        collectionBinder.setCascadeStrategy(getCascadeStrategy(null, hibernateCascade, false, false));
        collectionBinder.setOneToMany(false);
    }
    collectionBinder.setMappedBy(mappedBy);
    bindJoinedTableAssociation(property, context, entityBinder, collectionBinder, propertyHolder, inferredData, mappedBy);
    OnDelete onDeleteAnn = property.getAnnotation(OnDelete.class);
    boolean onDeleteCascade = onDeleteAnn != null && OnDeleteAction.CASCADE == onDeleteAnn.action();
    collectionBinder.setCascadeDeleteEnabled(onDeleteCascade);
    if (isIdentifierMapper) {
        collectionBinder.setInsertable(false);
        collectionBinder.setUpdatable(false);
    }
    if (property.isAnnotationPresent(CollectionId.class)) {
        // do not compute the generators unless necessary
        HashMap<String, IdentifierGeneratorDefinition> localGenerators = new HashMap<>(classGenerators);
        localGenerators.putAll(buildGenerators(property, context));
        collectionBinder.setLocalGenerators(localGenerators);
    }
    collectionBinder.setInheritanceStatePerClass(inheritanceStatePerClass);
    collectionBinder.setDeclaringClass(inferredData.getDeclaringClass());
    collectionBinder.bind();
}
Also used : HashMap(java.util.HashMap) SortNatural(org.hibernate.annotations.SortNatural) ManyToAny(org.hibernate.annotations.ManyToAny) Formula(org.hibernate.annotations.Formula) DiscriminatorFormula(org.hibernate.annotations.DiscriminatorFormula) MapKeyJoinColumn(jakarta.persistence.MapKeyJoinColumn) JoinColumn(jakarta.persistence.JoinColumn) PrimaryKeyJoinColumn(jakarta.persistence.PrimaryKeyJoinColumn) AnnotationException(org.hibernate.AnnotationException) SortComparator(org.hibernate.annotations.SortComparator) ElementCollection(jakarta.persistence.ElementCollection) Embedded(jakarta.persistence.Embedded) Cascade(org.hibernate.annotations.Cascade) OrderBy(org.hibernate.annotations.OrderBy) BatchSize(org.hibernate.annotations.BatchSize) Comment(org.hibernate.annotations.Comment) ReflectionManager(org.hibernate.annotations.common.reflection.ReflectionManager) OrderColumn(jakarta.persistence.OrderColumn) ManyToMany(jakarta.persistence.ManyToMany) AnnotatedJoinColumn.buildJoinTableJoinColumns(org.hibernate.cfg.AnnotatedJoinColumn.buildJoinTableJoinColumns) JoinColumns(jakarta.persistence.JoinColumns) PrimaryKeyJoinColumns(jakarta.persistence.PrimaryKeyJoinColumns) Columns(org.hibernate.annotations.Columns) MapKeyJoinColumns(jakarta.persistence.MapKeyJoinColumns) ListIndexBase(org.hibernate.annotations.ListIndexBase) OneToMany(jakarta.persistence.OneToMany) MapKey(jakarta.persistence.MapKey) IdentifierGeneratorDefinition(org.hibernate.boot.model.IdentifierGeneratorDefinition) XClass(org.hibernate.annotations.common.reflection.XClass) RootClass(org.hibernate.mapping.RootClass) PersistentClass(org.hibernate.mapping.PersistentClass) IdClass(jakarta.persistence.IdClass) CollectionBinder(org.hibernate.cfg.annotations.CollectionBinder) CollectionBinder.getCollectionBinder(org.hibernate.cfg.annotations.CollectionBinder.getCollectionBinder) Cache(org.hibernate.annotations.Cache) NotFound(org.hibernate.annotations.NotFound) OnDelete(org.hibernate.annotations.OnDelete)

Example 2 with ElementCollection

use of jakarta.persistence.ElementCollection in project hibernate-orm by hibernate.

the class CollectionBinder method defineFetchingStrategy.

private void defineFetchingStrategy() {
    LazyCollection lazy = property.getAnnotation(LazyCollection.class);
    Fetch fetch = property.getAnnotation(Fetch.class);
    OneToMany oneToMany = property.getAnnotation(OneToMany.class);
    ManyToMany manyToMany = property.getAnnotation(ManyToMany.class);
    ElementCollection elementCollection = property.getAnnotation(ElementCollection.class);
    ManyToAny manyToAny = property.getAnnotation(ManyToAny.class);
    FetchType fetchType;
    if (oneToMany != null) {
        fetchType = oneToMany.fetch();
    } else if (manyToMany != null) {
        fetchType = manyToMany.fetch();
    } else if (elementCollection != null) {
        fetchType = elementCollection.fetch();
    } else if (manyToAny != null) {
        fetchType = FetchType.LAZY;
    } else {
        throw new AssertionFailure("Define fetch strategy on a property not annotated with @ManyToOne nor @OneToMany nor @ElementCollection");
    }
    if (lazy != null) {
        collection.setLazy(!(lazy.value() == LazyCollectionOption.FALSE));
        collection.setExtraLazy(lazy.value() == LazyCollectionOption.EXTRA);
    } else {
        collection.setLazy(fetchType == FetchType.LAZY);
        collection.setExtraLazy(false);
    }
    if (fetch != null) {
        if (fetch.value() == org.hibernate.annotations.FetchMode.JOIN) {
            collection.setFetchMode(FetchMode.JOIN);
            collection.setLazy(false);
        } else if (fetch.value() == org.hibernate.annotations.FetchMode.SELECT) {
            collection.setFetchMode(FetchMode.SELECT);
        } else if (fetch.value() == org.hibernate.annotations.FetchMode.SUBSELECT) {
            collection.setFetchMode(FetchMode.SELECT);
            collection.setSubselectLoadable(true);
            collection.getOwner().setSubselectLoadableCollections(true);
        } else {
            throw new AssertionFailure("Unknown FetchMode: " + fetch.value());
        }
    } else {
        collection.setFetchMode(AnnotationBinder.getFetchMode(fetchType));
    }
}
Also used : Fetch(org.hibernate.annotations.Fetch) ManyToAny(org.hibernate.annotations.ManyToAny) AssertionFailure(org.hibernate.AssertionFailure) LazyCollection(org.hibernate.annotations.LazyCollection) FetchType(jakarta.persistence.FetchType) ManyToMany(jakarta.persistence.ManyToMany) ElementCollection(jakarta.persistence.ElementCollection) OneToMany(jakarta.persistence.OneToMany)

Example 3 with ElementCollection

use of jakarta.persistence.ElementCollection in project hibernate-orm by hibernate.

the class Ejb3XmlElementCollectionTest method testNoChildren.

@Test
public void testNoChildren() throws Exception {
    reader = getReader(Entity2.class, "field1", "element-collection.orm1.xml");
    assertAnnotationPresent(ElementCollection.class);
    assertAnnotationNotPresent(OrderBy.class);
    assertAnnotationNotPresent(OrderColumn.class);
    assertAnnotationNotPresent(MapKey.class);
    assertAnnotationNotPresent(MapKeyClass.class);
    assertAnnotationNotPresent(MapKeyTemporal.class);
    assertAnnotationNotPresent(MapKeyEnumerated.class);
    assertAnnotationNotPresent(MapKeyColumn.class);
    assertAnnotationNotPresent(MapKeyJoinColumns.class);
    assertAnnotationNotPresent(MapKeyJoinColumn.class);
    assertAnnotationNotPresent(Column.class);
    assertAnnotationNotPresent(Temporal.class);
    assertAnnotationNotPresent(Enumerated.class);
    assertAnnotationNotPresent(Lob.class);
    assertAnnotationNotPresent(AttributeOverride.class);
    assertAnnotationNotPresent(AttributeOverrides.class);
    assertAnnotationNotPresent(AssociationOverride.class);
    assertAnnotationNotPresent(AssociationOverrides.class);
    assertAnnotationNotPresent(CollectionTable.class);
    assertAnnotationNotPresent(Access.class);
    ElementCollection relAnno = reader.getAnnotation(ElementCollection.class);
    assertEquals(FetchType.LAZY, relAnno.fetch());
    assertEquals(void.class, relAnno.targetClass());
}
Also used : ElementCollection(jakarta.persistence.ElementCollection) Test(org.junit.Test)

Example 4 with ElementCollection

use of jakarta.persistence.ElementCollection in project jackson-datatype-hibernate by FasterXML.

the class PersistentCollectionSerializer method usesLazyLoading.

/**
 * Method called to see whether given property indicates it uses lazy
 * resolution of reference contained.
 */
protected boolean usesLazyLoading(BeanProperty property) {
    if (property != null) {
        // As per [Issue#36]
        ElementCollection ec = property.getAnnotation(ElementCollection.class);
        if (ec != null) {
            return (ec.fetch() == FetchType.LAZY);
        }
        OneToMany ann1 = property.getAnnotation(OneToMany.class);
        if (ann1 != null) {
            return (ann1.fetch() == FetchType.LAZY);
        }
        OneToOne ann2 = property.getAnnotation(OneToOne.class);
        if (ann2 != null) {
            return (ann2.fetch() == FetchType.LAZY);
        }
        ManyToOne ann3 = property.getAnnotation(ManyToOne.class);
        if (ann3 != null) {
            return (ann3.fetch() == FetchType.LAZY);
        }
        ManyToMany ann4 = property.getAnnotation(ManyToMany.class);
        if (ann4 != null) {
            return (ann4.fetch() == FetchType.LAZY);
        }
        // As per [Issue#53]
        return !Feature.REQUIRE_EXPLICIT_LAZY_LOADING_MARKER.enabledIn(_features);
    }
    return false;
}
Also used : OneToOne(jakarta.persistence.OneToOne) ManyToMany(jakarta.persistence.ManyToMany) ElementCollection(jakarta.persistence.ElementCollection) OneToMany(jakarta.persistence.OneToMany) ManyToOne(jakarta.persistence.ManyToOne)

Example 5 with ElementCollection

use of jakarta.persistence.ElementCollection in project hibernate-orm by hibernate.

the class BasicValueBinder method prepareCollectionElement.

private void prepareCollectionElement(XProperty attributeXProperty, XClass elementTypeXClass) {
    XClass xclass = elementTypeXClass == null && attributeXProperty.isArray() ? attributeXProperty.getElementClass() : elementTypeXClass;
    Class<?> javaType = resolveJavaType(xclass);
    implicitJavaTypeAccess = typeConfiguration -> javaType;
    final Temporal temporalAnn = attributeXProperty.getAnnotation(Temporal.class);
    if (temporalAnn != null) {
        temporalPrecision = temporalAnn.value();
        if (temporalPrecision == null) {
            throw new IllegalStateException("No jakarta.persistence.TemporalType defined for @jakarta.persistence.Temporal " + "associated with attribute " + attributeXProperty.getDeclaringClass().getName() + '.' + attributeXProperty.getName());
        }
    } else {
        temporalPrecision = null;
    }
    if (javaType.isEnum()) {
        final Enumerated enumeratedAnn = attributeXProperty.getAnnotation(Enumerated.class);
        if (enumeratedAnn != null) {
            enumType = enumeratedAnn.value();
            if (enumType == null) {
                throw new IllegalStateException("jakarta.persistence.EnumType was null on @jakarta.persistence.Enumerated " + " associated with attribute " + attributeXProperty.getDeclaringClass().getName() + '.' + attributeXProperty.getName());
            }
        }
    } else {
        enumType = null;
    }
    final TimeZoneStorage timeZoneStorageAnn = attributeXProperty.getAnnotation(TimeZoneStorage.class);
    timeZoneStorageType = timeZoneStorageAnn != null ? timeZoneStorageAnn.value() : null;
    normalSupplementalDetails(attributeXProperty);
    // layer in support for JPA's approach for specifying a specific Java type for the collection elements...
    final ElementCollection elementCollectionAnn = attributeXProperty.getAnnotation(ElementCollection.class);
    if (elementCollectionAnn != null && elementCollectionAnn.targetClass() != null && elementCollectionAnn.targetClass() != void.class) {
        final Function<TypeConfiguration, BasicJavaType> original = explicitJavaTypeAccess;
        explicitJavaTypeAccess = (typeConfiguration) -> {
            final BasicJavaType<?> originalResult = original.apply(typeConfiguration);
            if (originalResult != null) {
                return originalResult;
            }
            return (BasicJavaType<?>) typeConfiguration.getJavaTypeRegistry().getDescriptor(elementCollectionAnn.targetClass());
        };
    }
}
Also used : MapKeyEnumerated(jakarta.persistence.MapKeyEnumerated) Enumerated(jakarta.persistence.Enumerated) BasicJavaType(org.hibernate.type.descriptor.java.BasicJavaType) Temporal(jakarta.persistence.Temporal) MapKeyTemporal(jakarta.persistence.MapKeyTemporal) ElementCollection(jakarta.persistence.ElementCollection) TypeConfiguration(org.hibernate.type.spi.TypeConfiguration) XClass(org.hibernate.annotations.common.reflection.XClass) TimeZoneStorage(org.hibernate.annotations.TimeZoneStorage)

Aggregations

ElementCollection (jakarta.persistence.ElementCollection)6 ManyToMany (jakarta.persistence.ManyToMany)3 OneToMany (jakarta.persistence.OneToMany)3 ManyToAny (org.hibernate.annotations.ManyToAny)2 XClass (org.hibernate.annotations.common.reflection.XClass)2 Embedded (jakarta.persistence.Embedded)1 Enumerated (jakarta.persistence.Enumerated)1 FetchType (jakarta.persistence.FetchType)1 IdClass (jakarta.persistence.IdClass)1 JoinColumn (jakarta.persistence.JoinColumn)1 JoinColumns (jakarta.persistence.JoinColumns)1 ManyToOne (jakarta.persistence.ManyToOne)1 MapKey (jakarta.persistence.MapKey)1 MapKeyEnumerated (jakarta.persistence.MapKeyEnumerated)1 MapKeyJoinColumn (jakarta.persistence.MapKeyJoinColumn)1 MapKeyJoinColumns (jakarta.persistence.MapKeyJoinColumns)1 MapKeyTemporal (jakarta.persistence.MapKeyTemporal)1 OneToOne (jakarta.persistence.OneToOne)1 OrderColumn (jakarta.persistence.OrderColumn)1 PrimaryKeyJoinColumn (jakarta.persistence.PrimaryKeyJoinColumn)1