下面列出了怎么用org.hibernate.mapping.ManyToOne的API类实例代码及写法,或者点击链接到github查看源代码。
public ManyToOneColumnBinder(
MappingDocument mappingDocument,
SingularAttributeSourceManyToOne manyToOneSource,
ManyToOne manyToOneBinding,
String referencedEntityName) {
this.mappingDocument = mappingDocument;
this.manyToOneSource = manyToOneSource;
this.manyToOneBinding = manyToOneBinding;
this.referencedEntityName = referencedEntityName;
boolean allNamed = true;
for ( RelationalValueSource relationalValueSource : manyToOneSource.getRelationalValueSources() ) {
if ( relationalValueSource instanceof ColumnSource ) {
if ( ( (ColumnSource) relationalValueSource ).getName() == null ) {
allNamed = false;
break;
}
}
}
this.allColumnsNamed = allNamed;
}
public ManyToOneFkSecondPass(
MappingDocument mappingDocument,
SingularAttributeSourceManyToOne manyToOneSource,
ManyToOne manyToOneBinding,
String referencedEntityName) {
super( manyToOneBinding, null );
if ( referencedEntityName == null ) {
throw new MappingException(
"entity name referenced by many-to-one required [" + manyToOneSource.getAttributeRole().getFullPath() + "]",
mappingDocument.getOrigin()
);
}
this.mappingDocument = mappingDocument;
this.manyToOneBinding = manyToOneBinding;
this.referencedEntityName = referencedEntityName;
this.referencedEntityAttributeName = manyToOneSource.getReferencedEntityAttributeName();
}
/**
* @param property The property to bind
* @param manyToOne The inverse side
*/
protected void bindUnidirectionalOneToManyInverseValues(ToMany property, ManyToOne manyToOne) {
PropertyConfig config = getPropertyConfig(property);
if (config == null) {
manyToOne.setLazy(true);
} else {
manyToOne.setIgnoreNotFound(config.getIgnoreNotFound());
final FetchMode fetch = config.getFetchMode();
if(!fetch.equals(FetchMode.JOIN) && !fetch.equals(FetchMode.EAGER)) {
manyToOne.setLazy(true);
}
final Boolean lazy = config.getLazy();
if(lazy != null) {
manyToOne.setLazy(lazy);
}
}
// set referenced entity
manyToOne.setReferencedEntityName(property.getAssociatedEntity().getName());
}
/**
* Binds a unidirectional one-to-many creating a psuedo back reference property in the process.
*
* @param property
* @param mappings
* @param collection
*/
protected void bindUnidirectionalOneToMany(org.grails.datastore.mapping.model.types.OneToMany property, InFlightMetadataCollector mappings, Collection collection) {
Value v = collection.getElement();
v.createForeignKey();
String entityName;
if (v instanceof ManyToOne) {
ManyToOne manyToOne = (ManyToOne) v;
entityName = manyToOne.getReferencedEntityName();
} else {
entityName = ((OneToMany) v).getReferencedEntityName();
}
collection.setInverse(false);
PersistentClass referenced = mappings.getEntityBinding(entityName);
Backref prop = new Backref();
PersistentEntity owner = property.getOwner();
prop.setEntityName(owner.getName());
prop.setName(UNDERSCORE + addUnderscore(owner.getJavaClass().getSimpleName(), property.getName()) + "Backref");
prop.setUpdateable(false);
prop.setInsertable(true);
prop.setCollectionRole(collection.getRole());
prop.setValue(collection.getKey());
prop.setOptional(true);
referenced.addProperty(prop);
}
/**
*/
protected void bindManyToOneValues(org.grails.datastore.mapping.model.types.Association property, ManyToOne manyToOne) {
PropertyConfig config = getPropertyConfig(property);
if (config != null && config.getFetchMode() != null) {
manyToOne.setFetchMode(config.getFetchMode());
}
else {
manyToOne.setFetchMode(FetchMode.DEFAULT);
}
manyToOne.setLazy(getLaziness(property));
if (config != null) {
manyToOne.setIgnoreNotFound(config.getIgnoreNotFound());
}
// set referenced entity
manyToOne.setReferencedEntityName(property.getAssociatedEntity().getName());
}
public void testProperCallbacks() {
ValueVisitor vv = new ValueVisitorValidator();
new Any(new Table()).accept(vv);
new Array(new RootClass()).accept(vv);
new Bag(new RootClass()).accept(vv);
new Component(new RootClass()).accept(vv);
new DependantValue(null,null).accept(vv);
new IdentifierBag(null).accept(vv);
new List(null).accept(vv);
new ManyToOne(null).accept(vv);
new Map(null).accept(vv);
new OneToMany(null).accept(vv);
new OneToOne(null, new RootClass() ).accept(vv);
new PrimitiveArray(null).accept(vv);
new Set(null).accept(vv);
new SimpleValue().accept(vv);
}
/**
* 构造ManyToOne
*/
private ManyToOne buildManyToOne(MetaProperty property, Table table,
String columnName) {
ManyToOne value = new ManyToOne(metadataCollector, table);
// value.setPropertyName(property.getName());
value.setTypeName(property.getType());
value.setReferencedEntityName(property.getType());
value.setLazy(property.isLazy());
buildColumn(columnName, IDGenerator.LEN, value, table);
value.createForeignKey();
return value;
}
public void doSecondPass(java.util.Map persistentClasses) throws MappingException {
if ( value instanceof ManyToOne ) {
ManyToOne manyToOne = (ManyToOne) value;
PersistentClass ref = (PersistentClass) persistentClasses.get( manyToOne.getReferencedEntityName() );
if ( ref == null ) {
throw new AnnotationException(
"@OneToOne or @ManyToOne on "
+ StringHelper.qualify( entityClassName, path )
+ " references an unknown entity: "
+ manyToOne.getReferencedEntityName()
);
}
manyToOne.setPropertyName( path );
BinderHelper.createSyntheticPropertyReference( columns, ref, null, manyToOne, false, buildingContext );
TableBinder.bindFk( ref, null, columns, manyToOne, unique, buildingContext );
/*
* HbmMetadataSourceProcessorImpl does this only when property-ref != null, but IMO, it makes sense event if it is null
*/
if ( !manyToOne.isIgnoreNotFound() ) manyToOne.createPropertyRefConstraints( persistentClasses );
}
else if ( value instanceof OneToOne ) {
value.createForeignKey();
}
else {
throw new AssertionFailure( "FkSecondPass for a wrong value type: " + value.getClass().getName() );
}
}
protected boolean isBidirectionalManyToOneWithListMapping(PersistentProperty grailsProperty, Property prop) {
if(grailsProperty instanceof Association) {
Association association = (Association) grailsProperty;
Association otherSide = association.getInverseSide();
return association.isBidirectional() && otherSide != null &&
prop.getValue() instanceof ManyToOne &&
List.class.isAssignableFrom(otherSide.getType());
}
return false;
}
protected String getAssociationDescription(Association grailsProperty) {
String assType = "unknown";
if (grailsProperty instanceof ManyToMany) {
assType = "many-to-many";
} else if (grailsProperty instanceof org.grails.datastore.mapping.model.types.OneToMany) {
assType = "one-to-many";
} else if (grailsProperty instanceof org.grails.datastore.mapping.model.types.OneToOne) {
assType = "one-to-one";
} else if (grailsProperty instanceof org.grails.datastore.mapping.model.types.ManyToOne) {
assType = "many-to-one";
} else if (grailsProperty.isEmbedded()) {
assType = "embedded";
}
return assType;
}
public static void bindManyToOne(Element node, ManyToOne manyToOne, String path,
boolean isNullable, Mappings mappings) throws MappingException {
bindColumnsOrFormula( node, manyToOne, path, isNullable, mappings );
initOuterJoinFetchSetting( node, manyToOne );
initLaziness( node, manyToOne, mappings, true );
Attribute ukName = node.attribute( "property-ref" );
if ( ukName != null ) {
manyToOne.setReferencedPropertyName( ukName.getValue() );
}
manyToOne.setReferencedEntityName( getEntityName( node, mappings ) );
String embed = node.attributeValue( "embed-xml" );
manyToOne.setEmbedded( embed == null || "true".equals( embed ) );
String notFound = node.attributeValue( "not-found" );
manyToOne.setIgnoreNotFound( "ignore".equals( notFound ) );
if( ukName != null && !manyToOne.isIgnoreNotFound() ) {
if ( !node.getName().equals("many-to-many") ) { //TODO: really bad, evil hack to fix!!!
mappings.addSecondPass( new ManyToOneSecondPass(manyToOne) );
}
}
Attribute fkNode = node.attribute( "foreign-key" );
if ( fkNode != null ) manyToOne.setForeignKeyName( fkNode.getValue() );
validateCascade( node, path );
}
/**
* bind the inverse FK of a ManyToMany
* If we are in a mappedBy case, read the columns from the associated
* collection element
* Otherwise delegates to the usual algorithm
*/
public static void bindManytoManyInverseFk(
PersistentClass referencedEntity,
Ejb3JoinColumn[] columns,
SimpleValue value,
boolean unique,
MetadataBuildingContext buildingContext) {
final String mappedBy = columns[0].getMappedBy();
if ( StringHelper.isNotEmpty( mappedBy ) ) {
final Property property = referencedEntity.getRecursiveProperty( mappedBy );
Iterator mappedByColumns;
if ( property.getValue() instanceof Collection ) {
mappedByColumns = ( (Collection) property.getValue() ).getKey().getColumnIterator();
}
else {
//find the appropriate reference key, can be in a join
Iterator joinsIt = referencedEntity.getJoinIterator();
KeyValue key = null;
while ( joinsIt.hasNext() ) {
Join join = (Join) joinsIt.next();
if ( join.containsProperty( property ) ) {
key = join.getKey();
break;
}
}
if ( key == null ) key = property.getPersistentClass().getIdentifier();
mappedByColumns = key.getColumnIterator();
}
while ( mappedByColumns.hasNext() ) {
Column column = (Column) mappedByColumns.next();
columns[0].linkValueUsingAColumnCopy( column, value );
}
String referencedPropertyName =
buildingContext.getMetadataCollector().getPropertyReferencedAssociation(
"inverse__" + referencedEntity.getEntityName(), mappedBy
);
if ( referencedPropertyName != null ) {
//TODO always a many to one?
( (ManyToOne) value ).setReferencedPropertyName( referencedPropertyName );
buildingContext.getMetadataCollector().addUniquePropertyReference(
referencedEntity.getEntityName(),
referencedPropertyName
);
}
( (ManyToOne) value ).setReferenceToPrimaryKey( referencedPropertyName == null );
value.createForeignKey();
}
else {
BinderHelper.createSyntheticPropertyReference( columns, referencedEntity, null, value, true, buildingContext );
TableBinder.bindFk( referencedEntity, null, columns, value, unique, buildingContext );
}
}
private Property createManyToOneAttribute(
MappingDocument sourceDocument,
SingularAttributeSourceManyToOne manyToOneSource,
ManyToOne manyToOneBinding,
String containingClassName) {
final String attributeName = manyToOneSource.getName();
final String referencedEntityName;
if ( manyToOneSource.getReferencedEntityName() != null ) {
referencedEntityName = manyToOneSource.getReferencedEntityName();
}
else {
Class reflectedPropertyClass = Helper.reflectedPropertyClass( sourceDocument, containingClassName, attributeName );
if ( reflectedPropertyClass != null ) {
referencedEntityName = reflectedPropertyClass.getName();
}
else {
prepareValueTypeViaReflection(
sourceDocument,
manyToOneBinding,
containingClassName,
attributeName,
manyToOneSource.getAttributeRole()
);
referencedEntityName = manyToOneBinding.getTypeName();
}
}
if ( manyToOneSource.isUnique() ) {
manyToOneBinding.markAsLogicalOneToOne();
}
bindManyToOneAttribute( sourceDocument, manyToOneSource, manyToOneBinding, referencedEntityName );
final String propertyRef = manyToOneBinding.getReferencedPropertyName();
if ( propertyRef != null ) {
handlePropertyReference(
sourceDocument,
manyToOneBinding.getReferencedEntityName(),
propertyRef,
true,
"<many-to-one name=\"" + manyToOneSource.getName() + "\"/>"
);
}
Property prop = new Property();
prop.setValue( manyToOneBinding );
bindProperty(
sourceDocument,
manyToOneSource,
prop
);
if ( StringHelper.isNotEmpty( manyToOneSource.getCascadeStyleName() ) ) {
// todo : would be better to delay this the end of binding (second pass, etc)
// in order to properly allow for a singular unique column for a many-to-one to
// also trigger a "logical one-to-one". As-is, this can occasionally lead to
// false exceptions if the many-to-one column binding is delayed and the
// uniqueness is indicated on the <column/> rather than on the <many-to-one/>
//
// Ideally, would love to see a SimpleValue#validate approach, rather than a
// SimpleValue#isValid that is then handled at a higher level (Property, etc).
// The reason being that the current approach misses the exact reason
// a "validation" fails since it loses "context"
if ( manyToOneSource.getCascadeStyleName().contains( "delete-orphan" ) ) {
if ( !manyToOneBinding.isLogicalOneToOne() ) {
throw new MappingException(
String.format(
Locale.ENGLISH,
"many-to-one attribute [%s] specified delete-orphan but is not specified as unique; " +
"remove delete-orphan cascading or specify unique=\"true\"",
manyToOneSource.getAttributeRole().getFullPath()
),
sourceDocument.getOrigin()
);
}
}
}
return prop;
}
private void bindManyToOneAttribute(
final MappingDocument sourceDocument,
final SingularAttributeSourceManyToOne manyToOneSource,
ManyToOne manyToOneBinding,
String referencedEntityName) {
// NOTE : no type information to bind
manyToOneBinding.setReferencedEntityName( referencedEntityName );
if ( StringHelper.isNotEmpty( manyToOneSource.getReferencedEntityAttributeName() ) ) {
manyToOneBinding.setReferencedPropertyName( manyToOneSource.getReferencedEntityAttributeName() );
manyToOneBinding.setReferenceToPrimaryKey( false );
}
else {
manyToOneBinding.setReferenceToPrimaryKey( true );
}
manyToOneBinding.setLazy( manyToOneSource.getFetchCharacteristics().getFetchTiming() == FetchTiming.DELAYED );
manyToOneBinding.setUnwrapProxy( manyToOneSource.getFetchCharacteristics().isUnwrapProxies() );
manyToOneBinding.setFetchMode(
manyToOneSource.getFetchCharacteristics().getFetchStyle() == FetchStyle.SELECT
? FetchMode.SELECT
: FetchMode.JOIN
);
if ( manyToOneSource.isEmbedXml() == Boolean.TRUE ) {
DeprecationLogger.DEPRECATION_LOGGER.logDeprecationOfEmbedXmlSupport();
}
manyToOneBinding.setIgnoreNotFound( manyToOneSource.isIgnoreNotFound() );
if ( StringHelper.isNotEmpty( manyToOneSource.getExplicitForeignKeyName() ) ) {
manyToOneBinding.setForeignKeyName( manyToOneSource.getExplicitForeignKeyName() );
}
final ManyToOneColumnBinder columnBinder = new ManyToOneColumnBinder(
sourceDocument,
manyToOneSource,
manyToOneBinding,
referencedEntityName
);
final boolean canBindColumnsImmediately = columnBinder.canProcessImmediately();
if ( canBindColumnsImmediately ) {
columnBinder.doSecondPass( null );
}
else {
sourceDocument.getMetadataCollector().addSecondPass( columnBinder );
}
if ( !manyToOneSource.isIgnoreNotFound() ) {
// we skip creating the FK here since this setting tells us there
// cannot be a suitable/proper FK
final ManyToOneFkSecondPass fkSecondPass = new ManyToOneFkSecondPass(
sourceDocument,
manyToOneSource,
manyToOneBinding,
referencedEntityName
);
if ( canBindColumnsImmediately && fkSecondPass.canProcessImmediately() ) {
fkSecondPass.doSecondPass( null );
}
else {
sourceDocument.getMetadataCollector().addSecondPass( fkSecondPass );
}
}
manyToOneBinding.setCascadeDeleteEnabled( manyToOneSource.isCascadeDeleteEnabled() );
}
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, component.getTable() ),
component.getComponentClassName()
);
}
else if ( SingularAttributeSourceEmbedded.class.isInstance( attributeSource ) ) {
attribute = createEmbeddedAttribute(
sourceDocument,
(SingularAttributeSourceEmbedded) attributeSource,
new Component( sourceDocument, component ),
component.getComponentClassName()
);
}
else if ( SingularAttributeSourceManyToOne.class.isInstance( attributeSource ) ) {
attribute = createManyToOneAttribute(
sourceDocument,
(SingularAttributeSourceManyToOne) attributeSource,
new ManyToOne( sourceDocument, component.getTable() ),
component.getComponentClassName()
);
}
else if ( SingularAttributeSourceOneToOne.class.isInstance( attributeSource ) ) {
attribute = createOneToOneAttribute(
sourceDocument,
(SingularAttributeSourceOneToOne) attributeSource,
new OneToOne( sourceDocument, component.getTable(), component.getOwner() ),
component.getComponentClassName()
);
}
else if ( SingularAttributeSourceAny.class.isInstance( attributeSource ) ) {
attribute = createAnyAssociationAttribute(
sourceDocument,
(SingularAttributeSourceAny) attributeSource,
new Any( sourceDocument, 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 );
}
}
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);
}
}
}
protected boolean isBidirectionalManyToOne(PersistentProperty currentGrailsProp) {
return ((currentGrailsProp instanceof org.grails.datastore.mapping.model.types.ManyToOne) && ((Association)currentGrailsProp).isBidirectional());
}
/**
* Binds a many-to-one relationship to the
*
*/
@SuppressWarnings("unchecked")
protected void bindManyToOne(Association property, ManyToOne manyToOne,
String path, InFlightMetadataCollector mappings, String sessionFactoryBeanName) {
NamingStrategy namingStrategy = getNamingStrategy(sessionFactoryBeanName);
bindManyToOneValues(property, manyToOne);
PersistentEntity refDomainClass = property instanceof ManyToMany ? property.getOwner() : property.getAssociatedEntity();
Mapping mapping = getMapping(refDomainClass);
boolean isComposite = hasCompositeIdentifier(mapping);
if (isComposite) {
CompositeIdentity ci = (CompositeIdentity) mapping.getIdentity();
bindCompositeIdentifierToManyToOne(property, manyToOne, ci, refDomainClass, path, sessionFactoryBeanName);
}
else {
if (property.isCircular() && (property instanceof ManyToMany)) {
PropertyConfig pc = getPropertyConfig(property);
if (pc.getColumns().isEmpty()) {
mapping.getColumns().put(property.getName(), pc);
}
if (!hasJoinKeyMapping(pc) ) {
JoinTable jt = new JoinTable();
final ColumnConfig columnConfig = new ColumnConfig();
columnConfig.setName(namingStrategy.propertyToColumnName(property.getName()) +
UNDERSCORE + FOREIGN_KEY_SUFFIX);
jt.setKey(columnConfig);
pc.setJoinTable(jt);
}
bindSimpleValue(property, manyToOne, path, pc, sessionFactoryBeanName);
}
else {
// bind column
bindSimpleValue(property, null, manyToOne, path, mappings, sessionFactoryBeanName);
}
}
PropertyConfig config = getPropertyConfig(property);
if ((property instanceof org.grails.datastore.mapping.model.types.OneToOne) && !isComposite) {
manyToOne.setAlternateUniqueKey(true);
Column c = getColumnForSimpleValue(manyToOne);
if (config != null && !config.isUniqueWithinGroup()) {
c.setUnique(config.isUnique());
}
else if (property.isBidirectional() && isHasOne(property.getInverseSide())) {
c.setUnique(true);
}
}
}
protected void setCascadeBehaviour(PersistentProperty grailsProperty, Property prop) {
String cascadeStrategy = "none";
// set to cascade all for the moment
PersistentEntity domainClass = grailsProperty.getOwner();
PropertyConfig config = getPropertyConfig(grailsProperty);
if (config != null && config.getCascade() != null) {
cascadeStrategy = config.getCascade();
} else if (grailsProperty instanceof Association) {
Association association = (Association) grailsProperty;
PersistentEntity referenced = association.getAssociatedEntity();
if (isHasOne(association)) {
cascadeStrategy = CASCADE_ALL;
}
else if (association instanceof org.grails.datastore.mapping.model.types.OneToOne) {
if (referenced != null && association.isOwningSide()) {
cascadeStrategy = CASCADE_ALL;
}
else {
cascadeStrategy = CASCADE_SAVE_UPDATE;
}
} else if (association instanceof org.grails.datastore.mapping.model.types.OneToMany) {
if (referenced != null && association.isOwningSide()) {
cascadeStrategy = CASCADE_ALL;
}
else {
cascadeStrategy = CASCADE_SAVE_UPDATE;
}
} else if (grailsProperty instanceof ManyToMany) {
if ((referenced != null && referenced.isOwningEntity(domainClass)) || association.isCircular()) {
cascadeStrategy = CASCADE_SAVE_UPDATE;
}
} else if (grailsProperty instanceof org.grails.datastore.mapping.model.types.ManyToOne) {
if (referenced != null && referenced.isOwningEntity(domainClass) && !isCircularAssociation(grailsProperty)) {
cascadeStrategy = CASCADE_ALL;
}
else if(isCompositeIdProperty((Mapping) domainClass.getMapping().getMappedForm(), grailsProperty)) {
cascadeStrategy = CASCADE_ALL;
}
else {
cascadeStrategy = CASCADE_NONE;
}
}
else if (grailsProperty instanceof Basic) {
cascadeStrategy = CASCADE_ALL;
}
else if (Map.class.isAssignableFrom(grailsProperty.getType())) {
referenced = association.getAssociatedEntity();
if (referenced != null && referenced.isOwningEntity(domainClass)) {
cascadeStrategy = CASCADE_ALL;
} else {
cascadeStrategy = CASCADE_SAVE_UPDATE;
}
}
logCascadeMapping(association, cascadeStrategy, referenced);
}
prop.setCascade(cascadeStrategy);
}
/**
* Called for Maps
*/
public static void bindMapSecondPass(Element node, Map map, java.util.Map classes,
Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
bindCollectionSecondPass( node, map, classes, mappings, inheritedMetas );
Iterator iter = node.elementIterator();
while ( iter.hasNext() ) {
Element subnode = (Element) iter.next();
String name = subnode.getName();
if ( "index".equals( name ) || "map-key".equals( name ) ) {
SimpleValue value = new SimpleValue( map.getCollectionTable() );
bindSimpleValue(
subnode,
value,
map.isOneToMany(),
IndexedCollection.DEFAULT_INDEX_COLUMN_NAME,
mappings
);
if ( !value.isTypeSpecified() ) {
throw new MappingException( "map index element must specify a type: "
+ map.getRole() );
}
map.setIndex( value );
map.setIndexNodeName( subnode.attributeValue("node") );
}
else if ( "index-many-to-many".equals( name ) || "map-key-many-to-many".equals( name ) ) {
ManyToOne mto = new ManyToOne( map.getCollectionTable() );
bindManyToOne(
subnode,
mto,
IndexedCollection.DEFAULT_INDEX_COLUMN_NAME,
map.isOneToMany(),
mappings
);
map.setIndex( mto );
}
else if ( "composite-index".equals( name ) || "composite-map-key".equals( name ) ) {
Component component = new Component( map );
bindComposite(
subnode,
component,
map.getRole() + ".index",
map.isOneToMany(),
mappings,
inheritedMetas
);
map.setIndex( component );
}
else if ( "index-many-to-any".equals( name ) ) {
Any any = new Any( map.getCollectionTable() );
bindAny( subnode, any, map.isOneToMany(), mappings );
map.setIndex( any );
}
}
// TODO: this is a bit of copy/paste from IndexedCollection.createPrimaryKey()
boolean indexIsFormula = false;
Iterator colIter = map.getIndex().getColumnIterator();
while ( colIter.hasNext() ) {
if ( ( (Selectable) colIter.next() ).isFormula() ) indexIsFormula = true;
}
if ( map.isOneToMany() && !map.getKey().isNullable() && !map.isInverse() && !indexIsFormula ) {
String entityName = ( (OneToMany) map.getElement() ).getReferencedEntityName();
PersistentClass referenced = mappings.getClass( entityName );
IndexBackref ib = new IndexBackref();
ib.setName( '_' + node.attributeValue( "name" ) + "IndexBackref" );
ib.setUpdateable( false );
ib.setSelectable( false );
ib.setCollectionRole( map.getRole() );
ib.setEntityName( map.getOwner().getEntityName() );
ib.setValue( map.getIndex() );
// ( (Column) ( (SimpleValue) ic.getIndex() ).getColumnIterator().next()
// ).setNullable(false);
referenced.addProperty( ib );
}
}
ManyToOneSecondPass(ManyToOne manyToOne) {
this.manyToOne = manyToOne;
}
public Object accept(ManyToOne mto) {
return validate(ManyToOne.class, mto);
}
/**
* Binds a many-to-many relationship. A many-to-many consists of
* - a key (a DependentValue)
* - an element
*
* The element is a ManyToOne from the association table to the target entity
*
* @param property The grails property
* @param element The ManyToOne element
* @param mappings The mappings
*/
protected void bindManyToMany(Association property, ManyToOne element,
InFlightMetadataCollector mappings, String sessionFactoryBeanName) {
bindManyToOne(property, element, EMPTY_PATH, mappings, sessionFactoryBeanName);
element.setReferencedEntityName(property.getOwner().getName());
}