use of org.hibernate.cfg.AnnotatedColumn in project hibernate-orm by hibernate.
the class CollectionBinder method handleManyToAny.
private void handleManyToAny(Collection collValue, AnnotatedJoinColumn[] inverseJoinColumns, boolean cascadeDeleteEnabled, XProperty property, MetadataBuildingContext buildingContext) {
// @ManyToAny
// Make sure that collTyp is never used during the @ManyToAny branch: it will be set to void.class
final PropertyData inferredData = new PropertyInferredData(null, property, "unsupported", buildingContext.getBootstrapContext().getReflectionManager());
XProperty prop = inferredData.getProperty();
final jakarta.persistence.Column discriminatorColumnAnn = prop.getAnnotation(jakarta.persistence.Column.class);
final Formula discriminatorFormulaAnn = getOverridableAnnotation(prop, Formula.class, buildingContext);
// override the table
for (AnnotatedColumn column : inverseJoinColumns) {
column.setTable(collValue.getCollectionTable());
}
ManyToAny anyAnn = property.getAnnotation(ManyToAny.class);
final Any any = BinderHelper.buildAnyValue(discriminatorColumnAnn, discriminatorFormulaAnn, inverseJoinColumns, inferredData, cascadeDeleteEnabled, anyAnn.fetch() == FetchType.LAZY, Nullability.NO_CONSTRAINT, propertyHolder, new EntityBinder(), true, buildingContext);
collValue.setElement(any);
}
use of org.hibernate.cfg.AnnotatedColumn in project hibernate-orm by hibernate.
the class IdBagBinder method bindStarToManySecondPass.
@Override
protected boolean bindStarToManySecondPass(Map<String, PersistentClass> persistentClasses, XClass collType, AnnotatedJoinColumn[] fkJoinColumns, AnnotatedJoinColumn[] keyColumns, AnnotatedJoinColumn[] inverseColumns, AnnotatedColumn[] elementColumns, boolean isEmbedded, XProperty property, boolean unique, TableBinder associationTableBinder, boolean ignoreNotFound, MetadataBuildingContext buildingContext) {
boolean result = super.bindStarToManySecondPass(persistentClasses, collType, fkJoinColumns, keyColumns, inverseColumns, elementColumns, isEmbedded, property, unique, associationTableBinder, ignoreNotFound, getBuildingContext());
final CollectionId collectionIdAnn = property.getAnnotation(CollectionId.class);
if (collectionIdAnn == null) {
throw new MappingException("idbag mapping missing @CollectionId");
}
final PropertyData propertyData = new WrappedInferredData(new PropertyInferredData(null, property, // default access should not be useful
null, buildingContext.getBootstrapContext().getReflectionManager()), "id");
final AnnotatedColumn[] idColumns = AnnotatedColumn.buildColumnsFromAnnotations(new Column[] { collectionIdAnn.column() }, null, Nullability.FORCED_NOT_NULL, propertyHolder, propertyData, Collections.emptyMap(), buildingContext);
// we need to make sure all id columns must be not-null.
for (AnnotatedColumn idColumn : idColumns) {
idColumn.setNullable(false);
}
final BasicValueBinder valueBinder = new BasicValueBinder(BasicValueBinder.Kind.COLLECTION_ID, buildingContext);
final Table table = collection.getCollectionTable();
valueBinder.setTable(table);
valueBinder.setColumns(idColumns);
valueBinder.setType(property, collType, null, null);
final BasicValue id = valueBinder.make();
((IdentifierCollection) collection).setIdentifier(id);
final String namedGenerator = collectionIdAnn.generator();
if ("identity".equals(namedGenerator)) {
throw new MappingException("IDENTITY generation not supported for CollectionId");
}
if ("assigned".equals(namedGenerator)) {
throw new MappingException("Assigned generation not supported for CollectionId");
}
if ("native".equals(namedGenerator)) {
throw new MappingException("Native generation not supported for CollectionId");
}
final String generatorName;
final String generatorType;
if ("sequence".equals(namedGenerator)) {
generatorType = namedGenerator;
generatorName = "";
} else if ("increment".equals(namedGenerator)) {
generatorType = namedGenerator;
generatorName = "";
} else {
generatorType = namedGenerator;
generatorName = namedGenerator;
}
id.setIdentifierGeneratorStrategy(generatorType);
if (buildingContext.getBootstrapContext().getJpaCompliance().isGlobalGeneratorScopeEnabled()) {
SecondPass secondPass = new IdGeneratorResolverSecondPass(id, property, generatorType, generatorName, getBuildingContext());
buildingContext.getMetadataCollector().addSecondPass(secondPass);
} else {
BinderHelper.makeIdGenerator(id, property, generatorType, generatorName, getBuildingContext(), localGenerators);
}
return result;
}
use of org.hibernate.cfg.AnnotatedColumn in project hibernate-orm by hibernate.
the class CollectionBinder method handleElementCollection.
private void handleElementCollection(Collection collValue, AnnotatedColumn[] elementColumns, boolean isEmbedded, XClass collType, XProperty property, PropertyHolder parentPropertyHolder, MetadataBuildingContext buildingContext, String hqlOrderBy) {
XClass elementClass;
AnnotatedClassType classType;
CollectionPropertyHolder holder;
if (BinderHelper.PRIMITIVE_NAMES.contains(collType.getName())) {
classType = AnnotatedClassType.NONE;
elementClass = null;
holder = PropertyHolderBuilder.buildPropertyHolder(collValue, collValue.getRole(), null, property, parentPropertyHolder, buildingContext);
} else {
elementClass = collType;
classType = buildingContext.getMetadataCollector().getClassType(elementClass);
holder = PropertyHolderBuilder.buildPropertyHolder(collValue, collValue.getRole(), elementClass, property, parentPropertyHolder, buildingContext);
// 'parentPropertyHolder' is the PropertyHolder for the owner of the collection
// 'holder' is the CollectionPropertyHolder.
// 'property' is the collection XProperty
parentPropertyHolder.startingProperty(property);
// force in case of attribute override
boolean attributeOverride = property.isAnnotationPresent(AttributeOverride.class) || property.isAnnotationPresent(AttributeOverrides.class);
// todo : force in the case of Convert annotation(s) with embedded paths (beyond key/value prefixes)?
if (isEmbedded || attributeOverride) {
classType = AnnotatedClassType.EMBEDDABLE;
}
}
final Class<? extends CompositeUserType<?>> compositeUserType = resolveCompositeUserType(property, elementClass, buildingContext);
if (AnnotatedClassType.EMBEDDABLE == classType || compositeUserType != null) {
holder.prepare(property);
EntityBinder entityBinder = new EntityBinder();
PersistentClass owner = collValue.getOwner();
final AccessType baseAccessType;
final Access accessAnn = property.getAnnotation(Access.class);
if (accessAnn != null) {
// the attribute is locally annotated with `@Access`, use that
baseAccessType = accessAnn.value() == PROPERTY ? AccessType.PROPERTY : AccessType.FIELD;
} else if (owner.getIdentifierProperty() != null) {
// use the access for the owning entity's id attribute, if one
baseAccessType = owner.getIdentifierProperty().getPropertyAccessorName().equals("property") ? AccessType.PROPERTY : AccessType.FIELD;
} else if (owner.getIdentifierMapper() != null && owner.getIdentifierMapper().getPropertySpan() > 0) {
// use the access for the owning entity's "id mapper", if one
Property prop = owner.getIdentifierMapper().getProperties().get(0);
baseAccessType = prop.getPropertyAccessorName().equals("property") ? AccessType.PROPERTY : AccessType.FIELD;
} else {
// otherwise...
throw new AssertionFailure("Unable to guess collection property accessor name");
}
// TODO be smart with isNullable
Component component = fillComponent(holder, getSpecialMembers(elementClass), baseAccessType, true, entityBinder, false, false, true, resolveCustomInstantiator(property, elementClass, buildingContext), compositeUserType, buildingContext, inheritanceStatePerClass);
collValue.setElement(component);
if (StringHelper.isNotEmpty(hqlOrderBy)) {
String orderBy = adjustUserSuppliedValueCollectionOrderingFragment(hqlOrderBy);
if (orderBy != null) {
collValue.setOrderBy(orderBy);
}
}
} else {
holder.prepare(property);
final BasicValueBinder elementBinder = new BasicValueBinder(BasicValueBinder.Kind.COLLECTION_ELEMENT, buildingContext);
elementBinder.setReturnedClassName(collType.getName());
if (elementColumns == null || elementColumns.length == 0) {
elementColumns = new AnnotatedColumn[1];
AnnotatedColumn column = new AnnotatedColumn();
column.setImplicit(false);
// not following the spec but more clean
column.setNullable(true);
column.setLogicalColumnName(Collection.DEFAULT_ELEMENT_COLUMN_NAME);
// TODO create an EMPTY_JOINS collection
column.setJoins(new HashMap<>());
column.setBuildingContext(buildingContext);
column.bind();
elementColumns[0] = column;
}
// override the table
for (AnnotatedColumn column : elementColumns) {
column.setTable(collValue.getCollectionTable());
}
elementBinder.setColumns(elementColumns);
elementBinder.setType(property, elementClass, collValue.getOwnerEntityName(), holder.resolveElementAttributeConverterDescriptor(property, elementClass));
elementBinder.setPersistentClassName(propertyHolder.getEntityName());
elementBinder.setAccessType(accessType);
collValue.setElement(elementBinder.make());
String orderBy = adjustUserSuppliedValueCollectionOrderingFragment(hqlOrderBy);
if (orderBy != null) {
collValue.setOrderBy(orderBy);
}
}
}
use of org.hibernate.cfg.AnnotatedColumn in project hibernate-orm by hibernate.
the class MapBinder method bindKeyFromAssociationTable.
private void bindKeyFromAssociationTable(XClass collType, Map<String, PersistentClass> persistentClasses, String mapKeyPropertyName, XProperty property, boolean isEmbedded, MetadataBuildingContext buildingContext, AnnotatedColumn[] mapKeyColumns, AnnotatedJoinColumn[] mapKeyManyToManyColumns, String targetPropertyName) {
if (mapKeyPropertyName != null) {
// this is an EJB3 @MapKey
PersistentClass associatedClass = persistentClasses.get(collType.getName());
if (associatedClass == null)
throw new AnnotationException("Associated class not found: " + collType);
Property mapProperty = BinderHelper.findPropertyByName(associatedClass, mapKeyPropertyName);
if (mapProperty == null) {
throw new AnnotationException("Map key property not found: " + collType + "." + mapKeyPropertyName);
}
org.hibernate.mapping.Map map = (org.hibernate.mapping.Map) this.collection;
// HHH-11005 - if InheritanceType.JOINED then need to find class defining the column
InheritanceState inheritanceState = inheritanceStatePerClass.get(collType);
PersistentClass targetPropertyPersistentClass = InheritanceType.JOINED.equals(inheritanceState.getType()) ? mapProperty.getPersistentClass() : associatedClass;
Value indexValue = createFormulatedValue(mapProperty.getValue(), map, targetPropertyName, associatedClass, targetPropertyPersistentClass, buildingContext);
map.setIndex(indexValue);
map.setMapKeyPropertyName(mapKeyPropertyName);
} else {
// this is a true Map mapping
// TODO ugly copy/paste from CollectionBinder.bindManyToManySecondPass
String mapKeyType;
Class<?> target = void.class;
/*
* target has priority over reflection for the map key type
* JPA 2 has priority
*/
if (property.isAnnotationPresent(MapKeyClass.class)) {
target = property.getAnnotation(MapKeyClass.class).value();
}
if (!void.class.equals(target)) {
mapKeyType = target.getName();
} else {
mapKeyType = property.getMapKey().getName();
}
PersistentClass collectionEntity = persistentClasses.get(mapKeyType);
boolean isIndexOfEntities = collectionEntity != null;
ManyToOne element = null;
org.hibernate.mapping.Map mapValue = (org.hibernate.mapping.Map) this.collection;
if (isIndexOfEntities) {
element = new ManyToOne(buildingContext, mapValue.getCollectionTable());
mapValue.setIndex(element);
element.setReferencedEntityName(mapKeyType);
// element.setFetchMode( fetchMode );
// element.setLazy( fetchMode != FetchMode.JOIN );
// make the second join non lazy
element.setFetchMode(FetchMode.JOIN);
element.setLazy(false);
// does not make sense for a map key element.setIgnoreNotFound( ignoreNotFound );
} else {
final XClass keyXClass;
AnnotatedClassType classType;
if (BinderHelper.PRIMITIVE_NAMES.contains(mapKeyType)) {
classType = AnnotatedClassType.NONE;
keyXClass = null;
} else {
final BootstrapContext bootstrapContext = buildingContext.getBootstrapContext();
final Class<Object> mapKeyClass = bootstrapContext.getClassLoaderAccess().classForName(mapKeyType);
keyXClass = bootstrapContext.getReflectionManager().toXClass(mapKeyClass);
classType = buildingContext.getMetadataCollector().getClassType(keyXClass);
// force in case of attribute override naming the key
if (isEmbedded || mappingDefinedAttributeOverrideOnMapKey(property)) {
classType = AnnotatedClassType.EMBEDDABLE;
}
}
CollectionPropertyHolder holder = buildPropertyHolder(mapValue, StringHelper.qualify(mapValue.getRole(), "mapkey"), keyXClass, property, propertyHolder, buildingContext);
// 'propertyHolder' is the PropertyHolder for the owner of the collection
// 'holder' is the CollectionPropertyHolder.
// 'property' is the collection XProperty
propertyHolder.startingProperty(property);
holder.prepare(property);
PersistentClass owner = mapValue.getOwner();
AccessType accessType;
// String accessType = access != null ? access.value() : null;
if (owner.getIdentifierProperty() != null) {
accessType = owner.getIdentifierProperty().getPropertyAccessorName().equals("property") ? AccessType.PROPERTY : AccessType.FIELD;
} else if (owner.getIdentifierMapper() != null && owner.getIdentifierMapper().getPropertySpan() > 0) {
Property prop = owner.getIdentifierMapper().getProperties().get(0);
accessType = prop.getPropertyAccessorName().equals("property") ? AccessType.PROPERTY : AccessType.FIELD;
} else {
throw new AssertionFailure("Unable to guess collection property accessor name");
}
final Class<? extends CompositeUserType<?>> compositeUserType = resolveCompositeUserType(property, keyXClass, buildingContext);
if (AnnotatedClassType.EMBEDDABLE.equals(classType) || compositeUserType != null) {
EntityBinder entityBinder = new EntityBinder();
PropertyData inferredData = isHibernateExtensionMapping() ? new PropertyPreloadedData(AccessType.PROPERTY, "index", keyXClass) : new PropertyPreloadedData(AccessType.PROPERTY, "key", keyXClass);
// "key" is the JPA 2 prefix for map keys
// TODO be smart with isNullable
Component component = AnnotationBinder.fillComponent(holder, inferredData, accessType, true, entityBinder, false, false, true, null, compositeUserType, buildingContext, inheritanceStatePerClass);
mapValue.setIndex(component);
} else {
final BasicValueBinder elementBinder = new BasicValueBinder(BasicValueBinder.Kind.MAP_KEY, buildingContext);
elementBinder.setReturnedClassName(mapKeyType);
AnnotatedColumn[] elementColumns = mapKeyColumns;
if (elementColumns == null || elementColumns.length == 0) {
elementColumns = new AnnotatedColumn[1];
AnnotatedColumn column = new AnnotatedColumn();
column.setImplicit(false);
column.setNullable(true);
column.setLength(Size.DEFAULT_LENGTH);
column.setLogicalColumnName(Collection.DEFAULT_KEY_COLUMN_NAME);
// TODO create an EMPTY_JOINS collection
column.setJoins(new HashMap<>());
column.setBuildingContext(buildingContext);
column.bind();
elementColumns[0] = column;
}
// override the table
for (AnnotatedColumn column : elementColumns) {
column.setTable(mapValue.getCollectionTable());
}
elementBinder.setColumns(elementColumns);
// do not call setType as it extracts the type from @Type
// the algorithm generally does not apply for map key anyway
elementBinder.setType(property, keyXClass, this.collection.getOwnerEntityName(), holder.mapKeyAttributeConverterDescriptor(property, keyXClass));
elementBinder.setPersistentClassName(propertyHolder.getEntityName());
elementBinder.setAccessType(accessType);
mapValue.setIndex(elementBinder.make());
}
}
// FIXME pass the Index Entity JoinColumns
if (!collection.isOneToMany()) {
// index column should not be null
for (AnnotatedJoinColumn col : mapKeyManyToManyColumns) {
col.forceNotNull();
}
}
if (element != null) {
final jakarta.persistence.ForeignKey foreignKey = getMapKeyForeignKey(property);
if (foreignKey != null) {
if (foreignKey.value() == ConstraintMode.NO_CONSTRAINT || foreignKey.value() == ConstraintMode.PROVIDER_DEFAULT && getBuildingContext().getBuildingOptions().isNoConstraintByDefault()) {
element.disableForeignKey();
} else {
element.setForeignKeyName(StringHelper.nullIfEmpty(foreignKey.name()));
element.setForeignKeyDefinition(StringHelper.nullIfEmpty(foreignKey.foreignKeyDefinition()));
}
}
}
if (isIndexOfEntities) {
bindManytoManyInverseFk(collectionEntity, mapKeyManyToManyColumns, element, // a map key column has no unique constraint
false, buildingContext);
}
}
}
Aggregations