use of org.hibernate.mapping.Component in project hibernate-orm by hibernate.
the class OneToOneSecondPass method doSecondPass.
//TODO refactor this code, there is a lot of duplication in this method
public void doSecondPass(Map persistentClasses) throws MappingException {
org.hibernate.mapping.OneToOne value = new org.hibernate.mapping.OneToOne(buildingContext.getMetadataCollector(), propertyHolder.getTable(), propertyHolder.getPersistentClass());
final String propertyName = inferredData.getPropertyName();
value.setPropertyName(propertyName);
String referencedEntityName = ToOneBinder.getReferenceEntityName(inferredData, targetEntity, buildingContext);
value.setReferencedEntityName(referencedEntityName);
AnnotationBinder.defineFetchingStrategy(value, inferredData.getProperty());
//value.setFetchMode( fetchMode );
value.setCascadeDeleteEnabled(cascadeOnDelete);
if (!optional)
value.setConstrained(true);
value.setForeignKeyType(value.isConstrained() ? ForeignKeyDirection.FROM_PARENT : ForeignKeyDirection.TO_PARENT);
PropertyBinder binder = new PropertyBinder();
binder.setName(propertyName);
binder.setValue(value);
binder.setCascade(cascadeStrategy);
binder.setAccessType(inferredData.getDefaultAccess());
Property prop = binder.makeProperty();
if (ignoreNotFound) {
prop.setOptional(true);
}
if (BinderHelper.isEmptyAnnotationValue(mappedBy)) {
/*
* we need to check if the columns are in the right order
* if not, then we need to create a many to one and formula
* but actually, since entities linked by a one to one need
* to share the same composite id class, this cannot happen in hibernate
*/
boolean rightOrder = true;
if (rightOrder) {
String path = StringHelper.qualify(propertyHolder.getPath(), propertyName);
final ToOneFkSecondPass secondPass = new ToOneFkSecondPass(value, joinColumns, //cannot have nullabe and unique on certain DBs
!optional, propertyHolder.getEntityOwnerClassName(), path, buildingContext);
secondPass.doSecondPass(persistentClasses);
//no column associated since its a one to one
propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
} else {
//this is a many to one with Formula
}
} else {
PersistentClass otherSide = (PersistentClass) persistentClasses.get(value.getReferencedEntityName());
Property otherSideProperty;
try {
if (otherSide == null) {
throw new MappingException("Unable to find entity: " + value.getReferencedEntityName());
}
otherSideProperty = BinderHelper.findPropertyByName(otherSide, mappedBy);
} catch (MappingException e) {
throw new AnnotationException("Unknown mappedBy in: " + StringHelper.qualify(ownerEntity, ownerProperty) + ", referenced property unknown: " + StringHelper.qualify(value.getReferencedEntityName(), mappedBy));
}
if (otherSideProperty == null) {
throw new AnnotationException("Unknown mappedBy in: " + StringHelper.qualify(ownerEntity, ownerProperty) + ", referenced property unknown: " + StringHelper.qualify(value.getReferencedEntityName(), mappedBy));
}
if (otherSideProperty.getValue() instanceof OneToOne) {
propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
} else if (otherSideProperty.getValue() instanceof ManyToOne) {
Iterator it = otherSide.getJoinIterator();
Join otherSideJoin = null;
while (it.hasNext()) {
Join otherSideJoinValue = (Join) it.next();
if (otherSideJoinValue.containsProperty(otherSideProperty)) {
otherSideJoin = otherSideJoinValue;
break;
}
}
if (otherSideJoin != null) {
//@OneToOne @JoinTable
Join mappedByJoin = buildJoinFromMappedBySide((PersistentClass) persistentClasses.get(ownerEntity), otherSideProperty, otherSideJoin);
ManyToOne manyToOne = new ManyToOne(buildingContext.getMetadataCollector(), mappedByJoin.getTable());
//FIXME use ignore not found here
manyToOne.setIgnoreNotFound(ignoreNotFound);
manyToOne.setCascadeDeleteEnabled(value.isCascadeDeleteEnabled());
manyToOne.setFetchMode(value.getFetchMode());
manyToOne.setLazy(value.isLazy());
manyToOne.setReferencedEntityName(value.getReferencedEntityName());
manyToOne.setUnwrapProxy(value.isUnwrapProxy());
prop.setValue(manyToOne);
Iterator otherSideJoinKeyColumns = otherSideJoin.getKey().getColumnIterator();
while (otherSideJoinKeyColumns.hasNext()) {
Column column = (Column) otherSideJoinKeyColumns.next();
Column copy = new Column();
copy.setLength(column.getLength());
copy.setScale(column.getScale());
copy.setValue(manyToOne);
copy.setName(column.getQuotedName());
copy.setNullable(column.isNullable());
copy.setPrecision(column.getPrecision());
copy.setUnique(column.isUnique());
copy.setSqlType(column.getSqlType());
copy.setCheckConstraint(column.getCheckConstraint());
copy.setComment(column.getComment());
copy.setDefaultValue(column.getDefaultValue());
manyToOne.addColumn(copy);
}
mappedByJoin.addProperty(prop);
} else {
propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
}
value.setReferencedPropertyName(mappedBy);
// HHH-6813
// Foo: @Id long id, @OneToOne(mappedBy="foo") Bar bar
// Bar: @Id @OneToOne Foo foo
boolean referencesDerivedId = false;
try {
referencesDerivedId = otherSide.getIdentifier() instanceof Component && ((Component) otherSide.getIdentifier()).getProperty(mappedBy) != null;
} catch (MappingException e) {
// ignore
}
boolean referenceToPrimaryKey = referencesDerivedId || mappedBy == null;
value.setReferenceToPrimaryKey(referenceToPrimaryKey);
// loop of attempts to resolve identifiers.
if (referencesDerivedId) {
((ManyToOne) otherSideProperty.getValue()).setReferenceToPrimaryKey(false);
}
String propertyRef = value.getReferencedPropertyName();
if (propertyRef != null) {
buildingContext.getMetadataCollector().addUniquePropertyReference(value.getReferencedEntityName(), propertyRef);
}
} else {
throw new AnnotationException("Referenced property not a (One|Many)ToOne: " + StringHelper.qualify(otherSide.getEntityName(), mappedBy) + " in mappedBy of " + StringHelper.qualify(ownerEntity, ownerProperty));
}
}
final ForeignKey fk = inferredData.getProperty().getAnnotation(ForeignKey.class);
if (fk != null && !BinderHelper.isEmptyAnnotationValue(fk.name())) {
value.setForeignKeyName(fk.name());
} else {
final javax.persistence.ForeignKey jpaFk = inferredData.getProperty().getAnnotation(javax.persistence.ForeignKey.class);
if (jpaFk != null) {
if (jpaFk.value() == ConstraintMode.NO_CONSTRAINT) {
value.setForeignKeyName("none");
} else {
value.setForeignKeyName(StringHelper.nullIfEmpty(jpaFk.name()));
value.setForeignKeyDefinition(StringHelper.nullIfEmpty(jpaFk.foreignKeyDefinition()));
}
}
}
}
use of org.hibernate.mapping.Component in project hibernate-orm by hibernate.
the class AttributeFactory method determineAttributeMetadata.
/**
* Here is most of the nuts and bolts of this factory, where we interpret the known JPA metadata
* against the known Hibernate metadata and build a descriptor for the attribute.
*
* @param attributeContext The attribute to be described
* @param memberResolver Strategy for how to resolve the member defining the attribute.
* @param <X> The owner type
* @param <Y> The attribute type
*
* @return The attribute description
*/
@SuppressWarnings({ "unchecked" })
private <X, Y> AttributeMetadata<X, Y> determineAttributeMetadata(AttributeContext<X> attributeContext, MemberResolver memberResolver) {
LOG.trace("Starting attribute metadata determination [" + attributeContext.getPropertyMapping().getName() + "]");
final Member member = memberResolver.resolveMember(attributeContext);
LOG.trace(" Determined member [" + member + "]");
final Value value = attributeContext.getPropertyMapping().getValue();
final org.hibernate.type.Type type = value.getType();
LOG.trace(" Determined type [name=" + type.getName() + ", class=" + type.getClass().getName() + "]");
if (type.isAnyType()) {
// ANY mappings are currently not supported in the JPA metamodel; see HHH-6589
if (context.isIgnoreUnsupported()) {
return null;
} else {
throw new UnsupportedOperationException("ANY not supported");
}
} else if (type.isAssociationType()) {
// collection or entity
if (type.isEntityType()) {
// entity
return new SingularAttributeMetadataImpl<X, Y>(attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, determineSingularAssociationAttributeType(member));
}
// collection
if (value instanceof Collection) {
final Collection collValue = (Collection) value;
final Value elementValue = collValue.getElement();
final org.hibernate.type.Type elementType = elementValue.getType();
// First, determine the type of the elements and use that to help determine the
// collection type)
final Attribute.PersistentAttributeType elementPersistentAttributeType;
final Attribute.PersistentAttributeType persistentAttributeType;
if (elementType.isAnyType()) {
if (context.isIgnoreUnsupported()) {
return null;
} else {
throw new UnsupportedOperationException("collection of any not supported yet");
}
}
final boolean isManyToMany = isManyToMany(member);
if (elementValue instanceof Component) {
elementPersistentAttributeType = Attribute.PersistentAttributeType.EMBEDDED;
persistentAttributeType = Attribute.PersistentAttributeType.ELEMENT_COLLECTION;
} else if (elementType.isAssociationType()) {
elementPersistentAttributeType = isManyToMany ? Attribute.PersistentAttributeType.MANY_TO_MANY : Attribute.PersistentAttributeType.ONE_TO_MANY;
persistentAttributeType = elementPersistentAttributeType;
} else {
elementPersistentAttributeType = Attribute.PersistentAttributeType.BASIC;
persistentAttributeType = Attribute.PersistentAttributeType.ELEMENT_COLLECTION;
}
final Attribute.PersistentAttributeType keyPersistentAttributeType;
// Finally, we determine the type of the map key (if needed)
if (value instanceof Map) {
final Value keyValue = ((Map) value).getIndex();
final org.hibernate.type.Type keyType = keyValue.getType();
if (keyType.isAnyType()) {
if (context.isIgnoreUnsupported()) {
return null;
} else {
throw new UnsupportedOperationException("collection of any not supported yet");
}
}
if (keyValue instanceof Component) {
keyPersistentAttributeType = Attribute.PersistentAttributeType.EMBEDDED;
} else if (keyType.isAssociationType()) {
keyPersistentAttributeType = Attribute.PersistentAttributeType.MANY_TO_ONE;
} else {
keyPersistentAttributeType = Attribute.PersistentAttributeType.BASIC;
}
} else {
keyPersistentAttributeType = null;
}
return new PluralAttributeMetadataImpl(attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, persistentAttributeType, elementPersistentAttributeType, keyPersistentAttributeType);
} else if (value instanceof OneToMany) {
// element value within a o.h.mapping.Collection (see logic branch above)
throw new IllegalArgumentException("HUH???");
// final boolean isManyToMany = isManyToMany( member );
// //one to many with FK => entity
// return new PluralAttributeMetadataImpl(
// attributeContext.getPropertyMapping(),
// attributeContext.getOwnerType(),
// member,
// isManyToMany
// ? Attribute.PersistentAttributeType.MANY_TO_MANY
// : Attribute.PersistentAttributeType.ONE_TO_MANY
// value,
// AttributeContext.TypeStatus.ENTITY,
// Attribute.PersistentAttributeType.ONE_TO_MANY,
// null, null, null
// );
}
} else if (attributeContext.getPropertyMapping().isComposite()) {
// component
return new SingularAttributeMetadataImpl<X, Y>(attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, Attribute.PersistentAttributeType.EMBEDDED);
} else {
// basic type
return new SingularAttributeMetadataImpl<X, Y>(attributeContext.getPropertyMapping(), attributeContext.getOwnerType(), member, Attribute.PersistentAttributeType.BASIC);
}
throw new UnsupportedOperationException("oops, we are missing something: " + attributeContext.getPropertyMapping());
}
use of org.hibernate.mapping.Component in project hibernate-orm by hibernate.
the class AbstractEntityPersister method internalInitSubclassPropertyAliasesMap.
private void internalInitSubclassPropertyAliasesMap(String path, Iterator propertyIterator) {
while (propertyIterator.hasNext()) {
Property prop = (Property) propertyIterator.next();
String propname = path == null ? prop.getName() : path + "." + prop.getName();
if (prop.isComposite()) {
Component component = (Component) prop.getValue();
Iterator compProps = component.getPropertyIterator();
internalInitSubclassPropertyAliasesMap(propname, compProps);
} else {
String[] aliases = new String[prop.getColumnSpan()];
String[] cols = new String[prop.getColumnSpan()];
Iterator colIter = prop.getColumnIterator();
int l = 0;
while (colIter.hasNext()) {
Selectable thing = (Selectable) colIter.next();
aliases[l] = thing.getAlias(getFactory().getDialect(), prop.getValue().getTable());
// TODO: skip formulas?
cols[l] = thing.getText(getFactory().getDialect());
l++;
}
subclassPropertyAliases.put(propname, aliases);
subclassPropertyColumnNames.put(propname, cols);
}
}
}
use of org.hibernate.mapping.Component in project hibernate-orm by hibernate.
the class CompositeElementTest method afterMetadataBuilt.
@Override
protected void afterMetadataBuilt(Metadata metadata) {
Collection children = metadata.getCollectionBinding(Parent.class.getName() + ".children");
Component childComponents = (Component) children.getElement();
Formula f = (Formula) childComponents.getProperty("bioLength").getValue().getColumnIterator().next();
SQLFunction lengthFunction = metadata.getDatabase().getJdbcEnvironment().getDialect().getFunctions().get("length");
if (lengthFunction != null) {
ArrayList args = new ArrayList();
args.add("bio");
f.setFormula(lengthFunction.render(StandardBasicTypes.INTEGER, args, null));
}
}
use of org.hibernate.mapping.Component in project hibernate-orm by hibernate.
the class ComponentTest method afterMetadataBuilt.
@Override
protected void afterMetadataBuilt(Metadata metadata) {
// Oracle and Postgres do not have year() functions, so we need to
// redefine the 'User.person.yob' formula
//
// consider temporary until we add the capability to define
// mapping formulas which can use dialect-registered functions...
PersistentClass user = metadata.getEntityBinding(User.class.getName());
org.hibernate.mapping.Property personProperty = user.getProperty("person");
Component component = (Component) personProperty.getValue();
Formula f = (Formula) component.getProperty("yob").getValue().getColumnIterator().next();
SQLFunction yearFunction = metadata.getDatabase().getJdbcEnvironment().getDialect().getFunctions().get("year");
if (yearFunction == null) {
// the dialect not know to support a year() function, so rely on the
// ANSI SQL extract function
f.setFormula("extract( year from dob )");
} else {
List args = new ArrayList();
args.add("dob");
f.setFormula(yearFunction.render(StandardBasicTypes.INTEGER, args, null));
}
}
Aggregations