in grails-datastore-gorm-hibernate/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java [262:340]
protected void bindListSecondPass(ToMany property, InFlightMetadataCollector mappings,
Map<?, ?> persistentClasses, org.hibernate.mapping.List list, String sessionFactoryBeanName) {
bindCollectionSecondPass(property, mappings, persistentClasses, list, sessionFactoryBeanName);
String columnName = getIndexColumnName(property, sessionFactoryBeanName);
final boolean isManyToMany = property instanceof ManyToMany;
if (isManyToMany && !property.isOwningSide()) {
throw new MappingException("Invalid association [" + property +
"]. List collection types only supported on the owning side of a many-to-many relationship.");
}
Table collectionTable = list.getCollectionTable();
SimpleValue iv = new SimpleValue(metadataBuildingContext, collectionTable);
bindSimpleValue("integer", iv, true, columnName, mappings);
iv.setTypeName("integer");
list.setIndex(iv);
list.setBaseIndex(0);
list.setInverse(false);
Value v = list.getElement();
v.createForeignKey();
if (property.isBidirectional()) {
String entityName;
Value element = list.getElement();
if (element instanceof ManyToOne) {
ManyToOne manyToOne = (ManyToOne) element;
entityName = manyToOne.getReferencedEntityName();
} else {
entityName = ((OneToMany) element).getReferencedEntityName();
}
PersistentClass referenced = mappings.getEntityBinding(entityName);
Class<?> mappedClass = referenced.getMappedClass();
Mapping m = getMapping(mappedClass);
boolean compositeIdProperty = isCompositeIdProperty(m, property.getInverseSide());
if (!compositeIdProperty) {
Backref prop = new Backref();
final PersistentEntity owner = property.getOwner();
prop.setEntityName(owner.getName());
prop.setName(UNDERSCORE + addUnderscore(owner.getJavaClass().getSimpleName(), property.getName()) + "Backref");
prop.setSelectable(false);
prop.setUpdateable(false);
if (isManyToMany) {
prop.setInsertable(false);
}
prop.setCollectionRole(list.getRole());
prop.setValue(list.getKey());
DependantValue value = (DependantValue) prop.getValue();
if (!property.isCircular()) {
value.setNullable(false);
}
value.setUpdateable(true);
prop.setOptional(false);
referenced.addProperty(prop);
}
if ((!list.getKey().isNullable() && !list.isInverse()) || compositeIdProperty) {
IndexBackref ib = new IndexBackref();
ib.setName(UNDERSCORE + property.getName() + "IndexBackref");
ib.setUpdateable(false);
ib.setSelectable(false);
if (isManyToMany) {
ib.setInsertable(false);
}
ib.setCollectionRole(list.getRole());
ib.setEntityName(list.getOwner().getEntityName());
ib.setValue(list.getIndex());
referenced.addProperty(ib);
}
}
}