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();
}
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));
}
}
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());
}
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;
}
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());
};
}
}
Aggregations