use of org.hibernate.mapping.Component in project hibernate-orm by hibernate.
the class AnnotationBinder method bindComponent.
private static PropertyBinder bindComponent(PropertyData inferredData, PropertyHolder propertyHolder, AccessType propertyAccessor, EntityBinder entityBinder, boolean isIdentifierMapper, MetadataBuildingContext buildingContext, boolean isComponentEmbedded, //is a identifier
boolean isId, Map<XClass, InheritanceState> inheritanceStatePerClass, //is a component who is overridden by a @MapsId
String referencedEntityName, Ejb3JoinColumn[] columns) {
Component comp;
if (referencedEntityName != null) {
comp = createComponent(propertyHolder, inferredData, isComponentEmbedded, isIdentifierMapper, buildingContext);
SecondPass sp = new CopyIdentifierComponentSecondPass(comp, referencedEntityName, columns, buildingContext);
buildingContext.getMetadataCollector().addSecondPass(sp);
} else {
comp = fillComponent(propertyHolder, inferredData, propertyAccessor, !isId, entityBinder, isComponentEmbedded, isIdentifierMapper, false, buildingContext, inheritanceStatePerClass);
}
if (isId) {
comp.setKey(true);
if (propertyHolder.getPersistentClass().getIdentifier() != null) {
throw new AnnotationException(comp.getComponentClassName() + " must not have @Id properties when used as an @EmbeddedId: " + BinderHelper.getPath(propertyHolder, inferredData));
}
if (referencedEntityName == null && comp.getPropertySpan() == 0) {
throw new AnnotationException(comp.getComponentClassName() + " has no persistent id property: " + BinderHelper.getPath(propertyHolder, inferredData));
}
}
XProperty property = inferredData.getProperty();
setupComponentTuplizer(property, comp);
PropertyBinder binder = new PropertyBinder();
binder.setDeclaringClass(inferredData.getDeclaringClass());
binder.setName(inferredData.getPropertyName());
binder.setValue(comp);
binder.setProperty(inferredData.getProperty());
binder.setAccessType(inferredData.getDefaultAccess());
binder.setEmbedded(isComponentEmbedded);
binder.setHolder(propertyHolder);
binder.setId(isId);
binder.setEntityBinder(entityBinder);
binder.setInheritanceStatePerClass(inheritanceStatePerClass);
binder.setBuildingContext(buildingContext);
binder.makePropertyAndBind();
return binder;
}
use of org.hibernate.mapping.Component in project hibernate-orm by hibernate.
the class AnnotationBinder method mapAsIdClass.
private static boolean mapAsIdClass(Map<XClass, InheritanceState> inheritanceStatePerClass, InheritanceState inheritanceState, PersistentClass persistentClass, EntityBinder entityBinder, PropertyHolder propertyHolder, InheritanceState.ElementsToProcess elementsToProcess, Set<String> idPropertiesIfIdClass, MetadataBuildingContext context) {
/*
* We are looking for @IdClass
* In general we map the id class as identifier using the mapping metadata of the main entity's properties
* and we create an identifier mapper containing the id properties of the main entity
*
* In JPA 2, there is a shortcut if the id class is the Pk of the associated class pointed to by the id
* it ought to be treated as an embedded and not a real IdClass (at least in the Hibernate's internal way
*/
XClass classWithIdClass = inheritanceState.getClassWithIdClass(false);
if (classWithIdClass != null) {
IdClass idClass = classWithIdClass.getAnnotation(IdClass.class);
XClass compositeClass = context.getBuildingOptions().getReflectionManager().toXClass(idClass.value());
PropertyData inferredData = new PropertyPreloadedData(entityBinder.getPropertyAccessType(), "id", compositeClass);
PropertyData baseInferredData = new PropertyPreloadedData(entityBinder.getPropertyAccessType(), "id", classWithIdClass);
AccessType propertyAccessor = entityBinder.getPropertyAccessor(compositeClass);
//In JPA 2, there is a shortcut if the IdClass is the Pk of the associated class pointed to by the id
//it ought to be treated as an embedded and not a real IdClass (at least in the Hibernate's internal way
final boolean isFakeIdClass = isIdClassPkOfTheAssociatedEntity(elementsToProcess, compositeClass, inferredData, baseInferredData, propertyAccessor, inheritanceStatePerClass, context);
if (isFakeIdClass) {
return false;
}
boolean isComponent = true;
String generatorType = "assigned";
String generator = BinderHelper.ANNOTATION_STRING_DEFAULT;
boolean ignoreIdAnnotations = entityBinder.isIgnoreIdAnnotations();
entityBinder.setIgnoreIdAnnotations(true);
propertyHolder.setInIdClass(true);
bindIdClass(generatorType, generator, inferredData, baseInferredData, null, propertyHolder, isComponent, propertyAccessor, entityBinder, true, false, context, inheritanceStatePerClass);
propertyHolder.setInIdClass(null);
inferredData = new PropertyPreloadedData(propertyAccessor, PropertyPath.IDENTIFIER_MAPPER_PROPERTY, compositeClass);
Component mapper = fillComponent(propertyHolder, inferredData, baseInferredData, propertyAccessor, false, entityBinder, true, true, false, context, inheritanceStatePerClass);
entityBinder.setIgnoreIdAnnotations(ignoreIdAnnotations);
persistentClass.setIdentifierMapper(mapper);
//If id definition is on a mapped superclass, update the mapping
final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(classWithIdClass, inheritanceStatePerClass, context);
if (superclass != null) {
superclass.setDeclaredIdentifierMapper(mapper);
} else {
//we are for sure on the entity
persistentClass.setDeclaredIdentifierMapper(mapper);
}
Property property = new Property();
property.setName(PropertyPath.IDENTIFIER_MAPPER_PROPERTY);
property.setUpdateable(false);
property.setInsertable(false);
property.setValue(mapper);
property.setPropertyAccessorName("embedded");
persistentClass.addProperty(property);
entityBinder.setIgnoreIdAnnotations(true);
Iterator properties = mapper.getPropertyIterator();
while (properties.hasNext()) {
idPropertiesIfIdClass.add(((Property) properties.next()).getName());
}
return true;
} else {
return false;
}
}
use of org.hibernate.mapping.Component in project hibernate-orm by hibernate.
the class AnnotationBinder method fillComponent.
public static Component fillComponent(PropertyHolder propertyHolder, PropertyData inferredData, //base inferred data correspond to the entity reproducing inferredData's properties (ie IdClass)
PropertyData baseInferredData, AccessType propertyAccessor, boolean isNullable, EntityBinder entityBinder, boolean isComponentEmbedded, boolean isIdentifierMapper, boolean inSecondPass, MetadataBuildingContext buildingContext, Map<XClass, InheritanceState> inheritanceStatePerClass) {
/**
* inSecondPass can only be used to apply right away the second pass of a composite-element
* Because it's a value type, there is no bidirectional association, hence second pass
* ordering does not matter
*/
Component comp = createComponent(propertyHolder, inferredData, isComponentEmbedded, isIdentifierMapper, buildingContext);
String subpath = BinderHelper.getPath(propertyHolder, inferredData);
LOG.tracev("Binding component with path: {0}", subpath);
PropertyHolder subHolder = PropertyHolderBuilder.buildPropertyHolder(comp, subpath, inferredData, propertyHolder, buildingContext);
// propertyHolder here is the owner of the component property. Tell it we are about to start the component...
propertyHolder.startingProperty(inferredData.getProperty());
final XClass xClassProcessed = inferredData.getPropertyClass();
List<PropertyData> classElements = new ArrayList<PropertyData>();
XClass returnedClassOrElement = inferredData.getClassOrElement();
List<PropertyData> baseClassElements = null;
Map<String, PropertyData> orderedBaseClassElements = new HashMap<String, PropertyData>();
XClass baseReturnedClassOrElement;
if (baseInferredData != null) {
baseClassElements = new ArrayList<PropertyData>();
baseReturnedClassOrElement = baseInferredData.getClassOrElement();
bindTypeDefs(baseReturnedClassOrElement, buildingContext);
// might be spread across the subclasses and super classes.
while (!Object.class.getName().equals(baseReturnedClassOrElement.getName())) {
PropertyContainer propContainer = new PropertyContainer(baseReturnedClassOrElement, xClassProcessed, propertyAccessor);
addElementsOfClass(baseClassElements, propContainer, buildingContext);
for (PropertyData element : baseClassElements) {
orderedBaseClassElements.put(element.getPropertyName(), element);
}
baseReturnedClassOrElement = baseReturnedClassOrElement.getSuperclass();
}
}
//embeddable elements can have type defs
bindTypeDefs(returnedClassOrElement, buildingContext);
PropertyContainer propContainer = new PropertyContainer(returnedClassOrElement, xClassProcessed, propertyAccessor);
addElementsOfClass(classElements, propContainer, buildingContext);
//add elements of the embeddable superclass
XClass superClass = xClassProcessed.getSuperclass();
while (superClass != null && superClass.isAnnotationPresent(MappedSuperclass.class)) {
//FIXME: proper support of typevariables incl var resolved at upper levels
propContainer = new PropertyContainer(superClass, xClassProcessed, propertyAccessor);
addElementsOfClass(classElements, propContainer, buildingContext);
superClass = superClass.getSuperclass();
}
if (baseClassElements != null) {
//useful to avoid breaking pre JPA 2 mappings
if (!hasAnnotationsOnIdClass(xClassProcessed)) {
for (int i = 0; i < classElements.size(); i++) {
final PropertyData idClassPropertyData = classElements.get(i);
final PropertyData entityPropertyData = orderedBaseClassElements.get(idClassPropertyData.getPropertyName());
if (propertyHolder.isInIdClass()) {
if (entityPropertyData == null) {
throw new AnnotationException("Property of @IdClass not found in entity " + baseInferredData.getPropertyClass().getName() + ": " + idClassPropertyData.getPropertyName());
}
final boolean hasXToOneAnnotation = entityPropertyData.getProperty().isAnnotationPresent(ManyToOne.class) || entityPropertyData.getProperty().isAnnotationPresent(OneToOne.class);
final boolean isOfDifferentType = !entityPropertyData.getClassOrElement().equals(idClassPropertyData.getClassOrElement());
if (hasXToOneAnnotation && isOfDifferentType) {
//don't replace here as we need to use the actual original return type
//the annotation overriding will be dealt with by a mechanism similar to @MapsId
} else {
//this works since they are in the same order
classElements.set(i, entityPropertyData);
}
} else {
//this works since they are in the same order
classElements.set(i, entityPropertyData);
}
}
}
}
for (PropertyData propertyAnnotatedElement : classElements) {
processElementAnnotations(subHolder, isNullable ? Nullability.NO_CONSTRAINT : Nullability.FORCED_NOT_NULL, propertyAnnotatedElement, new HashMap<String, IdentifierGeneratorDefinition>(), entityBinder, isIdentifierMapper, isComponentEmbedded, inSecondPass, buildingContext, inheritanceStatePerClass);
XProperty property = propertyAnnotatedElement.getProperty();
if (property.isAnnotationPresent(GeneratedValue.class) && property.isAnnotationPresent(Id.class)) {
//clone classGenerator and override with local values
Map<String, IdentifierGeneratorDefinition> localGenerators = new HashMap<String, IdentifierGeneratorDefinition>();
localGenerators.putAll(buildLocalGenerators(property, buildingContext));
GeneratedValue generatedValue = property.getAnnotation(GeneratedValue.class);
String generatorType = generatedValue != null ? generatorType(generatedValue.strategy(), buildingContext, property.getType()) : "assigned";
String generator = generatedValue != null ? generatedValue.generator() : BinderHelper.ANNOTATION_STRING_DEFAULT;
BinderHelper.makeIdGenerator((SimpleValue) comp.getProperty(property.getName()).getValue(), generatorType, generator, buildingContext, localGenerators);
}
}
return comp;
}
use of org.hibernate.mapping.Component in project hibernate-orm by hibernate.
the class ModelBinder method bindMapKey.
private void bindMapKey(final MappingDocument mappingDocument, final IndexedPluralAttributeSource pluralAttributeSource, final org.hibernate.mapping.Map collectionBinding) {
if (pluralAttributeSource.getIndexSource() instanceof PluralAttributeMapKeySourceBasic) {
final PluralAttributeMapKeySourceBasic mapKeySource = (PluralAttributeMapKeySourceBasic) pluralAttributeSource.getIndexSource();
final SimpleValue value = new SimpleValue(mappingDocument.getMetadataCollector(), collectionBinding.getCollectionTable());
bindSimpleValueType(mappingDocument, mapKeySource.getTypeInformation(), value);
if (!value.isTypeSpecified()) {
throw new MappingException("map index element must specify a type: " + pluralAttributeSource.getAttributeRole().getFullPath(), mappingDocument.getOrigin());
}
relationalObjectBinder.bindColumnsAndFormulas(mappingDocument, mapKeySource.getRelationalValueSources(), value, true, new RelationalObjectBinder.ColumnNamingDelegate() {
@Override
public Identifier determineImplicitName(LocalMetadataBuildingContext context) {
return database.toIdentifier(IndexedCollection.DEFAULT_INDEX_COLUMN_NAME);
}
});
collectionBinding.setIndex(value);
} else if (pluralAttributeSource.getIndexSource() instanceof PluralAttributeMapKeySourceEmbedded) {
final PluralAttributeMapKeySourceEmbedded mapKeySource = (PluralAttributeMapKeySourceEmbedded) pluralAttributeSource.getIndexSource();
final Component componentBinding = new Component(mappingDocument.getMetadataCollector(), collectionBinding);
bindComponent(mappingDocument, mapKeySource.getEmbeddableSource(), componentBinding, null, pluralAttributeSource.getName(), mapKeySource.getXmlNodeName(), false);
collectionBinding.setIndex(componentBinding);
} else if (pluralAttributeSource.getIndexSource() instanceof PluralAttributeMapKeyManyToManySource) {
final PluralAttributeMapKeyManyToManySource mapKeySource = (PluralAttributeMapKeyManyToManySource) pluralAttributeSource.getIndexSource();
final ManyToOne mapKeyBinding = new ManyToOne(mappingDocument.getMetadataCollector(), collectionBinding.getCollectionTable());
mapKeyBinding.setReferencedEntityName(mapKeySource.getReferencedEntityName());
relationalObjectBinder.bindColumnsAndFormulas(mappingDocument, mapKeySource.getRelationalValueSources(), mapKeyBinding, true, new RelationalObjectBinder.ColumnNamingDelegate() {
@Override
public Identifier determineImplicitName(final LocalMetadataBuildingContext context) {
return implicitNamingStrategy.determineMapKeyColumnName(new ImplicitMapKeyColumnNameSource() {
@Override
public AttributePath getPluralAttributePath() {
return pluralAttributeSource.getAttributePath();
}
@Override
public MetadataBuildingContext getBuildingContext() {
return context;
}
});
}
});
collectionBinding.setIndex(mapKeyBinding);
} else if (pluralAttributeSource.getIndexSource() instanceof PluralAttributeMapKeyManyToAnySource) {
final PluralAttributeMapKeyManyToAnySource mapKeySource = (PluralAttributeMapKeyManyToAnySource) pluralAttributeSource.getIndexSource();
final Any mapKeyBinding = new Any(mappingDocument.getMetadataCollector(), collectionBinding.getCollectionTable());
bindAny(mappingDocument, mapKeySource, mapKeyBinding, pluralAttributeSource.getAttributeRole().append("key"), pluralAttributeSource.getAttributePath().append("key"));
collectionBinding.setIndex(mapKeyBinding);
}
}
use of org.hibernate.mapping.Component in project hibernate-orm by hibernate.
the class ModelBinder method bindAllCompositeAttributes.
private void bindAllCompositeAttributes(MappingDocument sourceDocument, EmbeddableSource embeddableSource, Component component) {
for (AttributeSource attributeSource : embeddableSource.attributeSources()) {
Property attribute = null;
if (SingularAttributeSourceBasic.class.isInstance(attributeSource)) {
attribute = createBasicAttribute(sourceDocument, (SingularAttributeSourceBasic) attributeSource, new SimpleValue(sourceDocument.getMetadataCollector(), component.getTable()), component.getComponentClassName());
} else if (SingularAttributeSourceEmbedded.class.isInstance(attributeSource)) {
attribute = createEmbeddedAttribute(sourceDocument, (SingularAttributeSourceEmbedded) attributeSource, new Component(sourceDocument.getMetadataCollector(), component), component.getComponentClassName());
} else if (SingularAttributeSourceManyToOne.class.isInstance(attributeSource)) {
attribute = createManyToOneAttribute(sourceDocument, (SingularAttributeSourceManyToOne) attributeSource, new ManyToOne(sourceDocument.getMetadataCollector(), component.getTable()), component.getComponentClassName());
} else if (SingularAttributeSourceOneToOne.class.isInstance(attributeSource)) {
attribute = createOneToOneAttribute(sourceDocument, (SingularAttributeSourceOneToOne) attributeSource, new OneToOne(sourceDocument.getMetadataCollector(), component.getTable(), component.getOwner()), component.getComponentClassName());
} else if (SingularAttributeSourceAny.class.isInstance(attributeSource)) {
attribute = createAnyAssociationAttribute(sourceDocument, (SingularAttributeSourceAny) attributeSource, new Any(sourceDocument.getMetadataCollector(), component.getTable()), component.getComponentClassName());
} else if (PluralAttributeSource.class.isInstance(attributeSource)) {
attribute = createPluralAttribute(sourceDocument, (PluralAttributeSource) attributeSource, component.getOwner());
} else {
throw new AssertionFailure(String.format(Locale.ENGLISH, "Unexpected AttributeSource sub-type [%s] as part of composite [%s]", attributeSource.getClass().getName(), attributeSource.getAttributeRole().getFullPath()));
}
component.addProperty(attribute);
}
}
Aggregations