use of org.hibernate.mapping.Collection in project hibernate-orm by hibernate.
the class ListBinder method bindIndex.
private void bindIndex(final MetadataBuildingContext buildingContext) {
if (!indexColumn.isImplicit()) {
PropertyHolder valueHolder = PropertyHolderBuilder.buildPropertyHolder(this.collection, StringHelper.qualify(this.collection.getRole(), "key"), null, null, propertyHolder, getBuildingContext());
List list = (List) this.collection;
if (!list.isOneToMany())
indexColumn.forceNotNull();
indexColumn.setPropertyHolder(valueHolder);
SimpleValueBinder value = new SimpleValueBinder();
value.setColumns(new Ejb3Column[] { indexColumn });
value.setExplicitType("integer");
value.setBuildingContext(getBuildingContext());
SimpleValue indexValue = value.make();
indexColumn.linkWithValue(indexValue);
list.setIndex(indexValue);
list.setBaseIndex(indexColumn.getBase());
if (list.isOneToMany() && !list.getKey().isNullable() && !list.isInverse()) {
String entityName = ((OneToMany) list.getElement()).getReferencedEntityName();
PersistentClass referenced = buildingContext.getMetadataCollector().getEntityBinding(entityName);
IndexBackref ib = new IndexBackref();
ib.setName('_' + propertyName + "IndexBackref");
ib.setUpdateable(false);
ib.setSelectable(false);
ib.setCollectionRole(list.getRole());
ib.setEntityName(list.getOwner().getEntityName());
ib.setValue(list.getIndex());
referenced.addProperty(ib);
}
} else {
Collection coll = this.collection;
throw new AnnotationException("List/array has to be annotated with an @OrderColumn (or @IndexColumn): " + coll.getRole());
}
}
use of org.hibernate.mapping.Collection in project hibernate-orm by hibernate.
the class TableBinder method bindFk.
public static void bindFk(PersistentClass referencedEntity, PersistentClass destinationEntity, Ejb3JoinColumn[] columns, SimpleValue value, boolean unique, MetadataBuildingContext buildingContext) {
PersistentClass associatedClass;
if (destinationEntity != null) {
//overridden destination
associatedClass = destinationEntity;
} else {
associatedClass = columns[0].getPropertyHolder() == null ? null : columns[0].getPropertyHolder().getPersistentClass();
}
final String mappedByProperty = columns[0].getMappedBy();
if (StringHelper.isNotEmpty(mappedByProperty)) {
/**
* Get the columns of the mapped-by property
* copy them and link the copy to the actual value
*/
LOG.debugf("Retrieving property %s.%s", associatedClass.getEntityName(), mappedByProperty);
final Property property = associatedClass.getRecursiveProperty(columns[0].getMappedBy());
Iterator mappedByColumns;
if (property.getValue() instanceof Collection) {
Collection collection = ((Collection) property.getValue());
Value element = collection.getElement();
if (element == null) {
throw new AnnotationException("Illegal use of mappedBy on both sides of the relationship: " + associatedClass.getEntityName() + "." + mappedByProperty);
}
mappedByColumns = element.getColumnIterator();
} else {
mappedByColumns = property.getValue().getColumnIterator();
}
while (mappedByColumns.hasNext()) {
Column column = (Column) mappedByColumns.next();
columns[0].overrideFromReferencedColumnIfNecessary(column);
columns[0].linkValueUsingAColumnCopy(column, value);
}
} else if (columns[0].isImplicit()) {
/**
* if columns are implicit, then create the columns based on the
* referenced entity id columns
*/
Iterator idColumns;
if (referencedEntity instanceof JoinedSubclass) {
idColumns = referencedEntity.getKey().getColumnIterator();
} else {
idColumns = referencedEntity.getIdentifier().getColumnIterator();
}
while (idColumns.hasNext()) {
Column column = (Column) idColumns.next();
columns[0].linkValueUsingDefaultColumnNaming(column, referencedEntity, value);
columns[0].overrideFromReferencedColumnIfNecessary(column);
}
} else {
int fkEnum = Ejb3JoinColumn.checkReferencedColumnsType(columns, referencedEntity, buildingContext);
if (Ejb3JoinColumn.NON_PK_REFERENCE == fkEnum) {
String referencedPropertyName;
if (value instanceof ToOne) {
referencedPropertyName = ((ToOne) value).getReferencedPropertyName();
} else if (value instanceof DependantValue) {
String propertyName = columns[0].getPropertyName();
if (propertyName != null) {
Collection collection = (Collection) referencedEntity.getRecursiveProperty(propertyName).getValue();
referencedPropertyName = collection.getReferencedPropertyName();
} else {
throw new AnnotationException("SecondaryTable JoinColumn cannot reference a non primary key");
}
} else {
throw new AssertionFailure("Do a property ref on an unexpected Value type: " + value.getClass().getName());
}
if (referencedPropertyName == null) {
throw new AssertionFailure("No property ref found while expected");
}
Property synthProp = referencedEntity.getReferencedProperty(referencedPropertyName);
if (synthProp == null) {
throw new AssertionFailure("Cannot find synthProp: " + referencedEntity.getEntityName() + "." + referencedPropertyName);
}
linkJoinColumnWithValueOverridingNameIfImplicit(referencedEntity, synthProp.getColumnIterator(), columns, value);
} else {
if (Ejb3JoinColumn.NO_REFERENCE == fkEnum) {
//implicit case, we hope PK and FK columns are in the same order
if (columns.length != referencedEntity.getIdentifier().getColumnSpan()) {
throw new AnnotationException("A Foreign key refering " + referencedEntity.getEntityName() + " from " + associatedClass.getEntityName() + " has the wrong number of column. should be " + referencedEntity.getIdentifier().getColumnSpan());
}
linkJoinColumnWithValueOverridingNameIfImplicit(referencedEntity, referencedEntity.getIdentifier().getColumnIterator(), columns, value);
} else {
//explicit referencedColumnName
Iterator idColItr = referencedEntity.getKey().getColumnIterator();
org.hibernate.mapping.Column col;
//works cause the pk has to be on the primary table
Table table = referencedEntity.getTable();
if (!idColItr.hasNext()) {
LOG.debug("No column in the identifier!");
}
while (idColItr.hasNext()) {
boolean match = false;
//for each PK column, find the associated FK column.
col = (org.hibernate.mapping.Column) idColItr.next();
for (Ejb3JoinColumn joinCol : columns) {
String referencedColumn = joinCol.getReferencedColumn();
referencedColumn = buildingContext.getMetadataCollector().getPhysicalColumnName(table, referencedColumn);
//In JPA 2 referencedColumnName is case insensitive
if (referencedColumn.equalsIgnoreCase(col.getQuotedName(buildingContext.getMetadataCollector().getDatabase().getJdbcEnvironment().getDialect()))) {
//proper join column
if (joinCol.isNameDeferred()) {
joinCol.linkValueUsingDefaultColumnNaming(col, referencedEntity, value);
} else {
joinCol.linkWithValue(value);
}
joinCol.overrideFromReferencedColumnIfNecessary(col);
match = true;
break;
}
}
if (!match) {
throw new AnnotationException("Column name " + col.getName() + " of " + referencedEntity.getEntityName() + " not found in JoinColumns.referencedColumnName");
}
}
}
}
}
value.createForeignKey();
if (unique) {
createUniqueConstraint(value);
}
}
use of org.hibernate.mapping.Collection 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.Collection in project hibernate-orm by hibernate.
the class CollectionBinderTest method testAssociatedClassException.
@Test
@TestForIssue(jiraKey = "HHH-10106")
public void testAssociatedClassException() throws SQLException {
final Collection collection = mock(Collection.class);
final Map persistentClasses = mock(Map.class);
final XClass collectionType = mock(XClass.class);
final MetadataBuildingContext buildingContext = mock(MetadataBuildingContext.class);
final InFlightMetadataCollector inFly = mock(InFlightMetadataCollector.class);
final PersistentClass persistentClass = mock(PersistentClass.class);
final Table table = mock(Table.class);
when(buildingContext.getMetadataCollector()).thenReturn(inFly);
when(persistentClasses.get(null)).thenReturn(null);
when(collection.getOwner()).thenReturn(persistentClass);
when(collectionType.getName()).thenReturn("List");
when(persistentClass.getTable()).thenReturn(table);
when(table.getName()).thenReturn("Hibernate");
CollectionBinder collectionBinder = new CollectionBinder(false) {
@Override
protected Collection createCollection(PersistentClass persistentClass) {
return null;
}
{
final PropertyHolder propertyHolder = Mockito.mock(PropertyHolder.class);
when(propertyHolder.getClassName()).thenReturn(CollectionBinderTest.class.getSimpleName());
this.propertyName = "abc";
this.propertyHolder = propertyHolder;
}
};
String expectMessage = "Association [abc] for entity [CollectionBinderTest] references unmapped class [List]";
try {
collectionBinder.bindOneToManySecondPass(collection, persistentClasses, null, collectionType, false, false, buildingContext, null);
} catch (MappingException e) {
assertEquals(expectMessage, e.getMessage());
}
}
use of org.hibernate.mapping.Collection in project hibernate-orm by hibernate.
the class DefaultNamingCollectionElementTest method checkDefaultCollectionTableName.
protected void checkDefaultCollectionTableName(Class<?> ownerEntityClass, String ownerCollectionPropertyName, String expectedCollectionTableName) {
final org.hibernate.mapping.Collection collection = metadata().getCollectionBinding(ownerEntityClass.getName() + '.' + ownerCollectionPropertyName);
final org.hibernate.mapping.Table table = collection.getCollectionTable();
assertEquals(expectedCollectionTableName, table.getName());
}
Aggregations