/******************************************************************************* * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Oracle - initial API and implementation from Oracle TopLink ******************************************************************************/ package org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.relational; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.eclipse.persistence.tools.workbench.mappingsmodel.MWModel; import org.eclipse.persistence.tools.workbench.mappingsmodel.ProblemConstants; import org.eclipse.persistence.tools.workbench.mappingsmodel.TopLinkOptionSet; import org.eclipse.persistence.tools.workbench.mappingsmodel.db.MWColumn; import org.eclipse.persistence.tools.workbench.mappingsmodel.db.MWColumnPair; import org.eclipse.persistence.tools.workbench.mappingsmodel.db.MWReference; import org.eclipse.persistence.tools.workbench.mappingsmodel.db.MWTable; import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWDescriptor; import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.relational.MWJoinFetchableMapping; import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.relational.MWRelationalClassDescriptor; import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.relational.MWRelationalDescriptor; import org.eclipse.persistence.tools.workbench.mappingsmodel.handles.MWHandle; import org.eclipse.persistence.tools.workbench.mappingsmodel.handles.MWMappingHandle; import org.eclipse.persistence.tools.workbench.mappingsmodel.handles.MWReferenceHandle; import org.eclipse.persistence.tools.workbench.mappingsmodel.handles.MWHandle.NodeReferenceScrubber; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.MWAbstractReferenceMapping; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.MWIndirectableMapping; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.MWMapping; import org.eclipse.persistence.tools.workbench.mappingsmodel.meta.MWClassAttribute; import org.eclipse.persistence.tools.workbench.mappingsmodel.query.MWQueryable; import org.eclipse.persistence.tools.workbench.utility.CollectionTools; import org.eclipse.persistence.tools.workbench.utility.filters.Filter; import org.eclipse.persistence.tools.workbench.utility.node.Node; import org.eclipse.persistence.descriptors.ClassDescriptor; import org.eclipse.persistence.descriptors.DescriptorEvent; import org.eclipse.persistence.mappings.DatabaseMapping; import org.eclipse.persistence.mappings.DirectToFieldMapping; import org.eclipse.persistence.mappings.ForeignReferenceMapping; import org.eclipse.persistence.mappings.OneToOneMapping; import org.eclipse.persistence.mappings.converters.ObjectTypeConverter; import org.eclipse.persistence.oxm.XMLDescriptor; import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping; import org.eclipse.persistence.oxm.mappings.XMLDirectMapping; public abstract class MWAbstractTableReferenceMapping extends MWAbstractReferenceMapping implements MWTableReferenceMapping, MWIndirectableMapping, MWJoinFetchableMapping { private MWReferenceHandle referenceHandle; private volatile boolean maintainsBidirectionalRelationship; public final static String MAINTAINS_BIDIRECTIONAL_RELATIONSHIP_PROPERTY = "maintainsBidirectionalRelationship"; private MWMappingHandle relationshipPartnerMappingHandle; public final static String RELATIONSHIP_PARTNER_MAPPING_PROPERTY = "relationshipPartnerMapping"; private volatile JoinFetchOption joinFetchOption; private static TopLinkOptionSet joinFetchOptions; /** Indicates whether the referenced object should always be batch read on read all queries. */ private volatile boolean batchReading; // **************** Constructors *************** /** Default constructor - for TopLink use only */ protected MWAbstractTableReferenceMapping() { super(); } protected MWAbstractTableReferenceMapping(MWRelationalClassDescriptor descriptor, MWClassAttribute attribute, String mappingName) { super(descriptor, attribute, mappingName); } // **************** Initialization *************** /** * initialize persistent state */ protected void initialize(Node parent) { super.initialize(parent); this.referenceHandle = new MWReferenceHandle(this, this.buildReferenceScrubber()); this.relationshipPartnerMappingHandle = new MWMappingHandle(this, this.buildRelationshipPartnerMappingScrubber()); this.joinFetchOption = (JoinFetchOption)MWJoinFetchableMapping.JoinFetchOptionSet.joinFetchOptions().topLinkOptionForMWModelOption(JOIN_FETCH_NONE); } // **************** Accessors *************** public JoinFetchOption getJoinFetchOption() { if (this.joinFetchOption == null) { this.joinFetchOption = (JoinFetchOption)MWJoinFetchableMapping.JoinFetchOptionSet.joinFetchOptions().topLinkOptionForMWModelOption(JOIN_FETCH_NONE); } return this.joinFetchOption; } public void setJoinFetchOption(JoinFetchOption newJoinFetchOption) { JoinFetchOption old = this.joinFetchOption; this.joinFetchOption = newJoinFetchOption; firePropertyChanged(JOIN_FETCH_PROPERTY, old, this.joinFetchOption); } public void setJoinFetchOption(String joinFetchOptions) { setJoinFetchOption((JoinFetchOption) MWJoinFetchableMapping.JoinFetchOptionSet.joinFetchOptions().topLinkOptionForMWModelOption(joinFetchOptions)); } public MWReference getReference() { return this.referenceHandle.getReference(); } public void setReference(MWReference newValue) { MWReference oldValue = getReference(); this.referenceHandle.setReference(newValue); this.firePropertyChanged(REFERENCE_PROPERTY, oldValue, newValue); this.getProject().recalculateAggregatePathsToColumn(this.getParentDescriptor()); } public boolean maintainsBidirectionalRelationship() { return this.maintainsBidirectionalRelationship; } public void setMaintainsBidirectionalRelationship(boolean newBoolean) { boolean oldBoolean = this.maintainsBidirectionalRelationship; this.maintainsBidirectionalRelationship = newBoolean; firePropertyChanged(MAINTAINS_BIDIRECTIONAL_RELATIONSHIP_PROPERTY, oldBoolean, newBoolean); if (newBoolean == false) { this.setRelationshipPartnerMapping(null); } } public MWMapping getRelationshipPartnerMapping() { return this.relationshipPartnerMappingHandle.getMapping(); } public Collection getRelationshipPartnerMappingChoices() { if (getReferenceDescriptor() == null) { return Collections.EMPTY_SET; } Collection choices = CollectionTools.collection(getReferenceDescriptor().mappings()); // only occurs if reference descriptor is this mapping's owning descriptor. A mapping can't very well // maintain a bidirectional relationship with itself. - pwf choices.remove(this); return choices; } public void setRelationshipPartnerMapping(MWMapping newValue) { Object oldValue = getRelationshipPartnerMapping(); this.relationshipPartnerMappingHandle.setMapping(newValue); firePropertyChanged(RELATIONSHIP_PARTNER_MAPPING_PROPERTY, oldValue, newValue); } public void setReferenceDescriptor(MWDescriptor newReferenceDescriptor) { if (getReferenceDescriptor() != newReferenceDescriptor) { setRelationshipPartnerMapping(null); } super.setReferenceDescriptor(newReferenceDescriptor); } public boolean descriptorIsValidReferenceDescriptor(MWDescriptor descriptor) { return ((MWRelationalDescriptor) descriptor).isTableDescriptor(); } public boolean usesBatchReading() { return this.batchReading; } public void setUsesBatchReading(boolean newValue) { boolean oldValue = this.batchReading; this.batchReading = newValue; this.firePropertyChanged(BATCH_READING_PROPERTY, oldValue, newValue); } // **************** MWRelationalMapping implementation *************** public boolean parentDescriptorIsAggregate() { return ((MWRelationalDescriptor) getParentDescriptor()).isAggregateDescriptor(); } public MWRelationalDescriptor getParentRelationalDescriptor() { return (MWRelationalDescriptor) getParentDescriptor(); } // **************** Automap support *************** public void automap() { super.automap(); this.automapTableReference(); this.automapIndirection(); } /** * this method is overridden in MWManyToManyMapping */ protected void automapTableReference() { if (this.getReference() != null) { return; // if we already have a reference, do nothing } MWRelationalDescriptor referenceDescriptor = (MWRelationalDescriptor) this.getReferenceDescriptor(); if (referenceDescriptor == null) { return; // if we don't have a reference descriptor, we can't find a reference } Collection candidateReferences = this.buildCandidateReferences(); if (candidateReferences.isEmpty()) { return; } // find the best reference Set sourceTables = CollectionTools.set(this.getParentRelationalDescriptor().associatedTables()); Set targetTables = CollectionTools.set(referenceDescriptor.associatedTables()); for (Iterator stream = candidateReferences.iterator(); stream.hasNext();) { MWReference reference = (MWReference) stream.next(); MWTable sourceTable = reference.getSourceTable(); MWTable targetTable = reference.getTargetTable(); if ((sourceTables.contains(sourceTable) && targetTables.contains(targetTable)) || (sourceTables.contains(targetTable) && targetTables.contains(sourceTable))) { this.setReference(reference); break; } } } /** * build and return the set of candidate references * that can be used by the mapping */ protected abstract Set buildCandidateReferences(); /** * convenience method for subclass implementations of #buildCandidateReferences(): * return all the references that point from the reference descriptor's table(s) * to the mapping's descriptor's table(s) ("target foreign key") */ protected Set buildCandidateTargetReferences() { MWRelationalDescriptor referenceDescriptor = (MWRelationalDescriptor) this.getReferenceDescriptor(); if (referenceDescriptor == null) { return Collections.EMPTY_SET; } Set candidateReferences = new HashSet(); Set targetTables = CollectionTools.set(this.getParentRelationalDescriptor().candidateTablesIncludingInherited()); for (Iterator sourceTables = referenceDescriptor.associatedTablesIncludingInherited(); sourceTables.hasNext(); ) { MWTable sourceTable = (MWTable) sourceTables.next(); for (Iterator references = sourceTable.references(); references.hasNext(); ) { MWReference refererence = (MWReference) references.next(); if (targetTables.contains(refererence.getTargetTable())) { candidateReferences.add(refererence); } } } return candidateReferences; } /** * convenience method for subclass implementations of #buildCandidateReferences(): * return all the references that point from the mapping's descriptor's table(s) * to the reference descriptor's table(s) ("source foreign key") */ protected Set buildCandidateSourceReferences() { MWRelationalDescriptor referenceDescriptor = (MWRelationalDescriptor) this.getReferenceDescriptor(); if (referenceDescriptor == null) { return Collections.EMPTY_SET; } Set candidateReferences = new HashSet(); Set targetTables = CollectionTools.set(referenceDescriptor.associatedTables()); for (Iterator sourceTables = this.getParentRelationalDescriptor().candidateTables(); sourceTables.hasNext(); ) { MWTable sourceTable = (MWTable) sourceTables.next(); for (Iterator references = sourceTable.references(); references.hasNext(); ) { MWReference reference = (MWReference) references.next(); if (targetTables.contains(reference.getTargetTable())) { candidateReferences.add(reference); } } } return candidateReferences; } protected void automapIndirection() { if (this.getInstanceVariable().isValueHolder()) { this.setUseValueHolderIndirection(); } } // ************* MWTableReferenceMapping implementation ************ public Iterator candidateReferences() { return this.buildCandidateReferences().iterator(); } public boolean referenceIsCandidate(MWReference reference) { return this.buildCandidateReferences().contains(reference); } // ************* MWQueryable implementation ************ public boolean isTraversableForBatchReadAttribute() { return true; } public boolean isValidForBatchReadAttribute() { return true; } public boolean isTraversableForJoinedAttribute() { return true; } public boolean isValidForJoinedAttribute() { return true; } // ************* Aggregate support ************ protected abstract boolean fieldIsWritten(MWColumnPair association); protected static class ColumnPairAggregateRuntimeFieldNameGenerator implements AggregateRuntimeFieldNameGenerator { MWAbstractTableReferenceMapping mapping; private MWColumnPair columnPair; private boolean source; ColumnPairAggregateRuntimeFieldNameGenerator(MWAbstractTableReferenceMapping mapping, MWColumnPair columnPair, boolean source) { super(); this.mapping = mapping; this.columnPair = columnPair; this.source = source; } public boolean fieldIsWritten() { return this.mapping.fieldIsWritten(this.columnPair); } public String fieldNameForRuntime() { MWColumn field; if (this.source) { field = this.columnPair.getSourceColumn(); } else { field = this.columnPair.getTargetColumn(); } return field.getName() + "_IN_REFERENCE_" + this.mapping.getReference().getName(); } public AggregateFieldDescription fullFieldDescription() { final MWColumn column; if (this.source) { column = this.columnPair.getSourceColumn(); } else { column = this.columnPair.getTargetColumn(); } return new AggregateFieldDescription() { public String getMessageKey() { return "AGGREGATE_FIELD_DESCRIPTION_FOR_REFERENCE"; } public Object[] getMessageArguments() { return new Object[] {column.getName(), ColumnPairAggregateRuntimeFieldNameGenerator.this.mapping.getReference().getName()}; } }; } public MWDescriptor owningDescriptor() { throw new UnsupportedOperationException(); } } public boolean isTableReferenceMapping(){ return true; } public boolean isManyToManyMapping(){ return false; } public boolean isOneToManyMapping(){ return false; } public boolean isQueryable() { return true; } // ************ MWQueryable implementation *********** public boolean allowsChildren() { return true; } public boolean allowsOuterJoin() { return allowsChildren(); } public boolean isLeaf(Filter queryableFilter) { return subQueryableElements(queryableFilter).size() == 0; } public List subQueryableElements(Filter queryableFilter) { List subQueryableElements = new ArrayList(); if (getReferenceDescriptor() != null) { subQueryableElements = ((MWRelationalDescriptor) getReferenceDescriptor()).getQueryables(queryableFilter); Collections.sort(subQueryableElements, DEFAULT_COMPARATOR); } return subQueryableElements; } public MWQueryable subQueryableElementAt(int index, Filter queryableFilter) { return (MWQueryable) subQueryableElements(queryableFilter).get(index); } public boolean isTraversableForQueryExpression() { return true; } public boolean isValidForQueryExpression() { return true; } public boolean isTraversableForReportQueryAttribute() { return true; } // ************* Mapping morphing support ************ /** * IMPORTANT: See MWRMapping class comment. */ public void initializeFromMWAbstractTableReferenceMapping(MWAbstractTableReferenceMapping oldMapping) { super.initializeFromMWAbstractTableReferenceMapping(oldMapping); this.setReference(oldMapping.getReference()); this.setMaintainsBidirectionalRelationship(oldMapping.maintainsBidirectionalRelationship()); this.setRelationshipPartnerMapping(oldMapping.getRelationshipPartnerMapping()); this.setUsesBatchReading(oldMapping.usesBatchReading()); } public void initializeFromMWRelationalDirectContainerMapping(MWRelationalDirectContainerMapping oldMapping) { super.initializeFromMWRelationalDirectContainerMapping(oldMapping); this.setReference(oldMapping.getReference()); this.setUsesBatchReading(oldMapping.usesBatchReading()); } public boolean isValidRelationshipPartner() { return true; } //********* model synchronization support ********* protected void addChildrenTo(List children) { super.addChildrenTo(children); children.add(this.referenceHandle); children.add(this.relationshipPartnerMappingHandle); } private NodeReferenceScrubber buildRelationshipPartnerMappingScrubber() { return new NodeReferenceScrubber() { public void nodeReferenceRemoved(Node node, MWHandle handle) { MWAbstractTableReferenceMapping.this.setRelationshipPartnerMapping(null); } public String toString() { return "MWAbstractTableReferenceMapping.buildRelationshipPartnerMappingScrubber()"; } }; } private NodeReferenceScrubber buildReferenceScrubber() { return new NodeReferenceScrubber() { public void nodeReferenceRemoved(Node node, MWHandle handle) { MWAbstractTableReferenceMapping.this.setReference(null); } public String toString() { return "MWAbstractTableReferenceMapping.buildReferenceScrubber()"; } }; } public void descriptorUnmapped(Collection mappings) { super.descriptorUnmapped(mappings); if (getRelationshipPartnerMapping() != null && mappings.contains(getRelationshipPartnerMapping())) { setRelationshipPartnerMapping(null); } } public void mappingReplaced(MWMapping oldMapping, MWMapping newMapping) { super.mappingReplaced(oldMapping, newMapping); if (oldMapping == getRelationshipPartnerMapping()) { setRelationshipPartnerMapping(newMapping); } } /** * Returns true if this mapping behaves like a 1-1, where the source table (e.g. EMPLOYEE) has * a foreign key to the target table (e.g., ADDRESS); **/ public boolean sourceReferenceFieldsAreFromSourceDescriptorTables() { return false; } // ************** Problem Handling ************** protected void addProblemsTo(List newProblems) { super.addProblemsTo(newProblems); this.checkReference(newProblems); this.addInvalidRelationshipPartnerProblemTo(newProblems); this.addHasNonMutualRelationshipPartnerProblemTo(newProblems); } protected String referenceDescriptorInvalidProblemString() { return ProblemConstants.MAPPING_REFERENCE_DESCRIPTOR_NOT_RELATIONAL_DESCRIPTOR; } private void checkReference(List newProblems) { // Verify that the mapping has a reference associated with it if (this.getReference() == null) { newProblems.add(this.buildProblem(ProblemConstants.MAPPING_TABLE_REFERENCE_NOT_SPECIFIED)); return; } if ( ! this.referenceIsCandidate(this.getReference())) { newProblems.add(this.buildProblem(ProblemConstants.MAPPING_TABLE_REFERENCE_INVALID)); } } private void addInvalidRelationshipPartnerProblemTo(List newProblems) { if ( ! this.maintainsBidirectionalRelationship()) { return; } if (this.getRelationshipPartnerMapping() == null) { newProblems.add(this.buildProblem(ProblemConstants.MAPPING_RELATIONSHIP_PARTNER_NOT_SPECIFIED)); } else if ( ! this.getRelationshipPartnerMapping().isValidRelationshipPartner()) { newProblems.add(this.buildProblem(ProblemConstants.MAPPING_RELATIONSHIP_PARTNER_INVALID)); } } private void addHasNonMutualRelationshipPartnerProblemTo(List newProblems) { MWMapping relationshipPartnerMapping = this.getRelationshipPartnerMapping(); if (this.maintainsBidirectionalRelationship() && (relationshipPartnerMapping != null)) { if ( ! (relationshipPartnerMapping.maintainsBidirectionalRelationship() && (relationshipPartnerMapping.getRelationshipPartnerMapping() == this))) { newProblems.add(this.buildProblem(ProblemConstants.MAPPING_RELATIONSHIP_PARTNER_NOT_MUTUAL)); } } } // ************** Runtime Conversion************** public DatabaseMapping runtimeMapping() { ForeignReferenceMapping runtimeMapping = (ForeignReferenceMapping) super.runtimeMapping(); if (this.getReference() == null) { return runtimeMapping; } if ((getReferenceDescriptor() != null) && (getReferenceDescriptor().getMWClass() != null)) { runtimeMapping.setReferenceClassName(getReferenceDescriptor().getMWClass().getName()); } if (maintainsBidirectionalRelationship()) { if (getRelationshipPartnerMapping() != null) { runtimeMapping.setRelationshipPartnerAttributeName(getRelationshipPartnerMapping().getInstanceVariable().getName()); } } this.joinFetchOption.setMWOptionOnTopLinkObject(runtimeMapping); runtimeMapping.setUsesBatchReading(usesBatchReading()); return runtimeMapping; } // **************** TopLink methods ***************** public static XMLDescriptor buildDescriptor() { XMLDescriptor descriptor = new XMLDescriptor(); descriptor.setJavaClass(MWAbstractTableReferenceMapping.class); descriptor.getInheritancePolicy().setParentClass(MWAbstractReferenceMapping.class); XMLDirectMapping mbdrMapping = (XMLDirectMapping) descriptor.addDirectMapping("maintainsBidirectionalRelationship", "maintains-bidirectional-relationship/text()"); mbdrMapping.setNullValue(Boolean.FALSE); XMLCompositeObjectMapping relationshipPartnerMapping = new XMLCompositeObjectMapping(); relationshipPartnerMapping.setAttributeName("relationshipPartnerMappingHandle"); relationshipPartnerMapping.setGetMethodName("getRelationshipPartnerMappingHandleForTopLink"); relationshipPartnerMapping.setSetMethodName("setRelationshipPartnerMappingHandleForTopLink"); relationshipPartnerMapping.setReferenceClass(MWMappingHandle.class); relationshipPartnerMapping.setXPath("relationship-partner-mapping-handle"); descriptor.addMapping(relationshipPartnerMapping); XMLCompositeObjectMapping referenceHandleMapping = new XMLCompositeObjectMapping(); referenceHandleMapping.setAttributeName("referenceHandle"); referenceHandleMapping.setGetMethodName("getReferenceHandleForTopLink"); referenceHandleMapping.setSetMethodName("setReferenceHandleForTopLink"); referenceHandleMapping.setReferenceClass(MWReferenceHandle.class); referenceHandleMapping.setXPath("reference-handle"); descriptor.addMapping(referenceHandleMapping); // Join Fetching ObjectTypeConverter joinFetchingConverter = new ObjectTypeConverter(); MWJoinFetchableMapping.JoinFetchOptionSet.joinFetchOptions().addConversionValuesForTopLinkTo(joinFetchingConverter); XMLDirectMapping joinFetchingMapping = new XMLDirectMapping(); joinFetchingMapping.setAttributeName("joinFetchOption"); joinFetchingMapping.setXPath("join-fetch-option/text()"); joinFetchingMapping.setNullValue(MWJoinFetchableMapping.JoinFetchOptionSet.joinFetchOptions().topLinkOptionForMWModelOption(JOIN_FETCH_NONE)); joinFetchingMapping.setConverter(joinFetchingConverter); descriptor.addMapping(joinFetchingMapping); // Batch Reading XMLDirectMapping batchReadingMapping = (XMLDirectMapping) descriptor.addDirectMapping("batchReading", "uses-batch-reading/text()"); batchReadingMapping.setNullValue(Boolean.FALSE); return descriptor; } /** * check for null */ private MWMappingHandle getRelationshipPartnerMappingHandleForTopLink() { return (this.relationshipPartnerMappingHandle.getMapping() == null) ? null : this.relationshipPartnerMappingHandle; } private void setRelationshipPartnerMappingHandleForTopLink(MWMappingHandle handle) { NodeReferenceScrubber scrubber = this.buildRelationshipPartnerMappingScrubber(); this.relationshipPartnerMappingHandle = ((handle == null) ? new MWMappingHandle(this, scrubber) : handle.setScrubber(scrubber)); } /** * check for null */ private MWReferenceHandle getReferenceHandleForTopLink() { return (this.referenceHandle.getReference() == null) ? null : this.referenceHandle; } private void setReferenceHandleForTopLink(MWReferenceHandle referenceHandle) { NodeReferenceScrubber scrubber = this.buildReferenceScrubber(); this.referenceHandle = ((referenceHandle == null) ? new MWReferenceHandle(this, scrubber) : referenceHandle.setScrubber(scrubber)); } protected void setJoinFetchingForToplink(String newJoinFetching) { this.joinFetchOption = (JoinFetchOption) MWJoinFetchableMapping.JoinFetchOptionSet.joinFetchOptions().topLinkOptionForMWModelOption(newJoinFetching); } public static XMLDescriptor legacy60BuildDescriptor() { XMLDescriptor descriptor = MWModel.legacy60BuildStandardDescriptor(); descriptor.setJavaClass(MWAbstractTableReferenceMapping.class); descriptor.getInheritancePolicy().setParentClass(MWAbstractReferenceMapping.class); XMLDirectMapping mbdrMapping = (XMLDirectMapping) descriptor.addDirectMapping("maintainsBidirectionalRelationship", "maintains-bidirectional-relationship/text()"); mbdrMapping.setNullValue(Boolean.FALSE); XMLCompositeObjectMapping relationshipPartnerMapping = new XMLCompositeObjectMapping(); relationshipPartnerMapping.setAttributeName("relationshipPartnerMappingHandle"); relationshipPartnerMapping.setGetMethodName("getRelationshipPartnerMappingHandleForTopLink"); relationshipPartnerMapping.setSetMethodName("setRelationshipPartnerMappingHandleForTopLink"); relationshipPartnerMapping.setReferenceClass(MWMappingHandle.class); relationshipPartnerMapping.setXPath("relationship-partner-mapping-handle"); descriptor.addMapping(relationshipPartnerMapping); XMLCompositeObjectMapping referenceHandleMapping = new XMLCompositeObjectMapping(); referenceHandleMapping.setAttributeName("referenceHandle"); referenceHandleMapping.setGetMethodName("getReferenceHandleForTopLink"); referenceHandleMapping.setSetMethodName("setReferenceHandleForTopLink"); referenceHandleMapping.setReferenceClass(MWReferenceHandle.class); referenceHandleMapping.setXPath("reference-handle"); descriptor.addMapping(referenceHandleMapping); // Batch Reading XMLDirectMapping batchReadingMapping = (XMLDirectMapping) descriptor.addDirectMapping("batchReading", "uses-batch-reading/text()"); batchReadingMapping.setNullValue(Boolean.FALSE); return descriptor; } @Override protected void legacy60PostBuild(DescriptorEvent event) { super.legacy60PostBuild(event); if (this.joinFetchOption == null) { this.joinFetchOption = (JoinFetchOption)MWJoinFetchableMapping.JoinFetchOptionSet.joinFetchOptions().topLinkOptionForMWModelOption(JOIN_FETCH_NONE); } } public TopLinkOptionSet joinFetchOptions() { if (joinFetchOptions == null) { joinFetchOptions = MWJoinFetchableMapping.JoinFetchOptionSet.joinFetchOptions(); } return joinFetchOptions; } }