1 21 package oracle.toplink.essentials.mappings; 23 24 import java.util.*; 25 import oracle.toplink.essentials.exceptions.*; 26 import oracle.toplink.essentials.expressions.*; 27 import oracle.toplink.essentials.internal.expressions.ObjectExpression; 28 import oracle.toplink.essentials.internal.helper.*; 29 import oracle.toplink.essentials.internal.sessions.*; 30 import oracle.toplink.essentials.sessions.DatabaseRecord; 31 import oracle.toplink.essentials.queryframework.*; 32 import oracle.toplink.essentials.internal.sessions.AbstractRecord; 33 import oracle.toplink.essentials.internal.sessions.AbstractSession; 34 import oracle.toplink.essentials.descriptors.ClassDescriptor; 35 import oracle.toplink.essentials.internal.queryframework.JoinedAttributeManager; 36 37 46 public class OneToOneMapping extends ObjectReferenceMapping implements RelationalMapping { 47 48 49 protected Map sourceToTargetKeyFields; 50 51 52 protected Map targetToSourceKeyFields; 53 54 55 56 protected boolean shouldVerifyDelete; 57 protected transient Expression privateOwnedCriteria; 58 59 60 protected boolean usesJoining; 61 62 66 public OneToOneMapping() { 67 this.selectionQuery = new ReadObjectQuery(); 68 this.sourceToTargetKeyFields = new HashMap(2); 69 this.targetToSourceKeyFields = new HashMap(2); 70 this.foreignKeyFields = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(1); 71 this.isForeignKeyRelationship = false; 72 this.shouldVerifyDelete = true; 73 this.usesJoining = false; 74 } 75 76 79 public boolean isRelationalMapping() { 80 return true; 81 } 82 83 96 public void addForeignKeyField(DatabaseField sourceForeignKeyField, DatabaseField targetPrimaryKeyField) { 97 setIsForeignKeyRelationship(true); 98 getForeignKeyFields().addElement(sourceForeignKeyField); 99 100 getSourceToTargetKeyFields().put(sourceForeignKeyField, targetPrimaryKeyField); 101 getTargetToSourceKeyFields().put(targetPrimaryKeyField, sourceForeignKeyField); 102 } 103 104 117 public void addForeignKeyFieldName(String sourceForeignKeyFieldName, String targetPrimaryKeyFieldName) { 118 addForeignKeyField(new DatabaseField(sourceForeignKeyFieldName), new DatabaseField(targetPrimaryKeyFieldName)); 119 } 120 121 137 public void addTargetForeignKeyField(DatabaseField targetForeignKeyField, DatabaseField sourcePrimaryKeyField) { 138 getSourceToTargetKeyFields().put(sourcePrimaryKeyField, targetForeignKeyField); 139 getTargetToSourceKeyFields().put(targetForeignKeyField, sourcePrimaryKeyField); 140 } 141 142 158 public void addTargetForeignKeyFieldName(String targetForeignKeyFieldName, String sourcePrimaryKeyFieldName) { 159 addTargetForeignKeyField(new DatabaseField(targetForeignKeyFieldName), new DatabaseField(sourcePrimaryKeyFieldName)); 160 } 161 162 166 public Expression buildObjectJoinExpression(Expression expression, Object value, AbstractSession session) { 167 Expression base = ((oracle.toplink.essentials.internal.expressions.ObjectExpression)expression).getBaseExpression(); 168 Expression foreignKeyJoin = null; 169 170 if (value == null) { 172 if (!isForeignKeyRelationship()) { 175 throw QueryException.cannotCompareTargetForeignKeysToNull(base, value, this); 176 } 177 for (Iterator sourceFieldsEnum = getSourceToTargetKeyFields().keySet().iterator(); 178 sourceFieldsEnum.hasNext();) { 179 DatabaseField field = (DatabaseField)sourceFieldsEnum.next(); 180 Expression join = null; 181 if (expression.isObjectExpression() && ((ObjectExpression)expression).shouldUseOuterJoin()){ 182 join = base.getField(field).equalOuterJoin(null); 183 } else { 184 join = base.getField(field).equal(null); 185 } 186 if (foreignKeyJoin == null) { 187 foreignKeyJoin = join; 188 } else { 189 foreignKeyJoin = foreignKeyJoin.and(join); 190 } 191 } 192 } else { 193 if (!getReferenceDescriptor().getJavaClass().isInstance(value)) { 194 throw QueryException.incorrectClassForObjectComparison(base, value, this); 195 } 196 197 Enumeration keyEnum = extractKeyFromReferenceObject(value, session).elements(); 198 for (Iterator sourceFieldsEnum = getSourceToTargetKeyFields().keySet().iterator(); 199 sourceFieldsEnum.hasNext();) { 200 DatabaseField field = (DatabaseField)sourceFieldsEnum.next(); 201 Expression join = null; 202 if (expression.isObjectExpression() && ((ObjectExpression)expression).shouldUseOuterJoin()){ 203 join = base.getField(field).equalOuterJoin(keyEnum.nextElement()); 204 } else { 205 join = base.getField(field).equal(keyEnum.nextElement()); 206 } 207 if (foreignKeyJoin == null) { 208 foreignKeyJoin = join; 209 } else { 210 foreignKeyJoin = foreignKeyJoin.and(join); 211 } 212 } 213 } 214 return foreignKeyJoin; 215 } 216 217 221 public Expression buildObjectJoinExpression(Expression expression, Expression argument, AbstractSession session) { 222 Expression base = ((oracle.toplink.essentials.internal.expressions.ObjectExpression)expression).getBaseExpression(); 223 Expression foreignKeyJoin = null; 224 Iterator targetFieldsEnum = getSourceToTargetKeyFields().values().iterator(); 225 for (Iterator sourceFieldsEnum = getSourceToTargetKeyFields().keySet().iterator(); 226 sourceFieldsEnum.hasNext();) { 227 DatabaseField sourceField = (DatabaseField)sourceFieldsEnum.next(); 228 DatabaseField targetField = (DatabaseField)targetFieldsEnum.next(); 229 Expression join = null; 230 if (expression.isObjectExpression() && ((ObjectExpression)expression).shouldUseOuterJoin()){ 231 join = base.getField(sourceField).equalOuterJoin(argument.getField(targetField)); 232 } else { 233 join = base.getField(sourceField).equal(argument.getField(targetField)); 234 } 235 if (foreignKeyJoin == null) { 236 foreignKeyJoin = join; 237 } else { 238 foreignKeyJoin = foreignKeyJoin.and(join); 239 } 240 } 241 return foreignKeyJoin; 242 } 243 244 249 public Object clone() { 250 OneToOneMapping clone = (OneToOneMapping)super.clone(); 251 clone.setForeignKeyFields(oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(getForeignKeyFields().size())); 252 clone.setSourceToTargetKeyFields(new HashMap(getSourceToTargetKeyFields().size())); 253 clone.setTargetToSourceKeyFields(new HashMap(getTargetToSourceKeyFields().size())); 254 Hashtable setOfFields = new Hashtable(getTargetToSourceKeyFields().size()); 255 256 for (Enumeration enumtr = getForeignKeyFields().elements(); enumtr.hasMoreElements();) { 258 DatabaseField field = (DatabaseField)enumtr.nextElement(); 259 DatabaseField fieldClone = (DatabaseField)field.clone(); 260 setOfFields.put(field, fieldClone); 261 clone.getForeignKeyFields().addElement(fieldClone); 262 } 263 264 for (Iterator sourceEnum = getSourceToTargetKeyFields().keySet().iterator(); 266 sourceEnum.hasNext();) { 267 DatabaseField sourceField = (DatabaseField)sourceEnum.next(); 268 DatabaseField targetField = (DatabaseField)getSourceToTargetKeyFields().get(sourceField); 269 270 DatabaseField targetClone; 271 DatabaseField sourceClone; 272 273 targetClone = (DatabaseField)setOfFields.get(targetField); 274 if (targetClone == null) { 275 targetClone = (DatabaseField)targetField.clone(); 276 setOfFields.put(targetField, targetClone); 277 } 278 sourceClone = (DatabaseField)setOfFields.get(sourceField); 279 if (sourceClone == null) { 280 sourceClone = (DatabaseField)sourceField.clone(); 281 setOfFields.put(sourceField, sourceClone); 282 } 283 clone.getSourceToTargetKeyFields().put(sourceClone, targetClone); 284 } 285 286 for (Iterator targetEnum = getTargetToSourceKeyFields().keySet().iterator(); 288 targetEnum.hasNext();) { 289 DatabaseField targetField = (DatabaseField)targetEnum.next(); 290 DatabaseField sourceField = (DatabaseField)getTargetToSourceKeyFields().get(targetField); 291 292 DatabaseField targetClone; 293 DatabaseField sourceClone; 294 295 targetClone = (DatabaseField)setOfFields.get(targetField); 296 if (targetClone == null) { 297 targetClone = (DatabaseField)targetField.clone(); 298 setOfFields.put(targetField, targetClone); 299 } 300 sourceClone = (DatabaseField)setOfFields.get(sourceField); 301 if (sourceClone == null) { 302 sourceClone = (DatabaseField)sourceField.clone(); 303 setOfFields.put(sourceField, sourceClone); 304 } 305 clone.getTargetToSourceKeyFields().put(targetClone, sourceClone); 306 } 307 return clone; 308 } 309 310 316 public void dontUseJoining() { 317 setUsesJoining(false); 318 } 319 320 324 protected Vector extractForeignKeyFromRow(AbstractRecord row, AbstractSession session) { 325 Vector key = new Vector(); 326 327 for (Iterator fieldEnum = getSourceToTargetKeyFields().keySet().iterator(); 328 fieldEnum.hasNext();) { 329 DatabaseField field = (DatabaseField)fieldEnum.next(); 330 Object value = row.get(field); 331 332 try { 334 value = session.getDatasourcePlatform().getConversionManager().convertObject(value, getDescriptor().getObjectBuilder().getFieldClassification(field)); 335 } catch (ConversionException e) { 336 throw ConversionException.couldNotBeConverted(this, getDescriptor(), e); 337 } 338 339 key.addElement(value); 340 } 341 342 return key; 343 } 344 345 349 protected Vector extractKeyFromReferenceObject(Object object, AbstractSession session) { 350 Vector key = new Vector(); 351 352 for (Iterator fieldEnum = getSourceToTargetKeyFields().values().iterator(); 353 fieldEnum.hasNext();) { 354 DatabaseField field = (DatabaseField)fieldEnum.next(); 355 356 if (object == null) { 357 key.addElement(null); 358 } else { 359 key.addElement(getReferenceDescriptor().getObjectBuilder().extractValueFromObjectForField(object, field, session)); 360 } 361 } 362 363 return key; 364 } 365 366 372 public Vector extractPrimaryKeysForReferenceObjectFromRow(AbstractRecord row) { 373 List primaryKeyFields = getReferenceDescriptor().getPrimaryKeyFields(); 374 Vector result = new Vector(primaryKeyFields.size()); 375 for (int index = 0; index < primaryKeyFields.size(); index++) { 376 DatabaseField targetKeyField = (DatabaseField)primaryKeyFields.get(index); 377 DatabaseField sourceKeyField = (DatabaseField)getTargetToSourceKeyFields().get(targetKeyField); 378 if (sourceKeyField == null) { 379 return new Vector(1); 380 } 381 result.addElement(row.get(sourceKeyField)); 382 } 383 return result; 384 } 385 386 391 public Class getFieldClassification(DatabaseField fieldToClassify) throws DescriptorException { 392 DatabaseField fieldInTarget = (DatabaseField)getSourceToTargetKeyFields().get(fieldToClassify); 393 if (fieldInTarget == null) { 394 return null; } 396 DatabaseMapping mapping = getReferenceDescriptor().getObjectBuilder().getMappingForField(fieldInTarget); 397 if (mapping == null) { 398 return null; } 400 return mapping.getFieldClassification(fieldInTarget); 401 } 402 403 408 public Vector getForeignKeyFieldNames() { 409 Vector fieldNames = new Vector(getForeignKeyFields().size()); 410 for (Enumeration fieldsEnum = getForeignKeyFields().elements(); 411 fieldsEnum.hasMoreElements();) { 412 fieldNames.addElement(((DatabaseField)fieldsEnum.nextElement()).getQualifiedName()); 413 } 414 415 return fieldNames; 416 } 417 418 422 protected Map getForeignKeysToPrimaryKeys() { 423 if (this.isForeignKeyRelationship()) { 424 return this.getSourceToTargetKeyFields(); 425 } else { 426 return this.getTargetToSourceKeyFields(); 427 } 428 } 429 430 435 public Vector getOrderedForeignKeyFields() { 436 List primaryKeyFields = getPrimaryKeyDescriptor().getPrimaryKeyFields(); 437 Vector result = new Vector(primaryKeyFields.size()); 438 439 for (int index = 0; index < primaryKeyFields.size(); index++) { 440 DatabaseField pkField = (DatabaseField)primaryKeyFields.get(index); 441 boolean found = false; 442 for (Iterator fkStream = this.getForeignKeysToPrimaryKeys().keySet().iterator(); 443 fkStream.hasNext();) { 444 DatabaseField fkField = (DatabaseField)fkStream.next(); 445 446 if (this.getForeignKeysToPrimaryKeys().get(fkField).equals(pkField)) { 447 found = true; 448 result.addElement(fkField); 449 break; 450 } 451 } 452 if (!found) { 453 throw DescriptorException.missingForeignKeyTranslation(this, pkField); 454 } 455 } 456 return result; 457 } 458 459 463 protected ClassDescriptor getPrimaryKeyDescriptor() { 464 if (this.isForeignKeyRelationship()) { 465 return this.getReferenceDescriptor(); 466 } else { 467 return this.getDescriptor(); 468 } 469 } 470 471 475 public Expression getPrivateOwnedCriteria() { 476 if (privateOwnedCriteria == null) { 477 initializePrivateOwnedCriteria(); 478 } 479 return privateOwnedCriteria; 480 } 481 482 486 public Vector getSourceToTargetKeyFieldAssociations() { 487 Vector associations = new Vector(getSourceToTargetKeyFields().size()); 488 Iterator sourceFieldEnum = getSourceToTargetKeyFields().keySet().iterator(); 489 Iterator targetFieldEnum = getSourceToTargetKeyFields().values().iterator(); 490 while (sourceFieldEnum.hasNext()) { 491 Object fieldValue = ((DatabaseField)sourceFieldEnum.next()).getQualifiedName(); 492 Object attributeValue = ((DatabaseField)targetFieldEnum.next()).getQualifiedName(); 493 associations.addElement(new Association(fieldValue, attributeValue)); 494 } 495 496 return associations; 497 } 498 499 503 public Map getSourceToTargetKeyFields() { 504 return sourceToTargetKeyFields; 505 } 506 507 511 public Map getTargetToSourceKeyFields() { 512 return targetToSourceKeyFields; 513 } 514 515 519 public void initialize(AbstractSession session) throws DescriptorException { 520 super.initialize(session); 521 522 for (Enumeration foreignKeysEnum = getForeignKeyFields().elements(); 524 foreignKeysEnum.hasMoreElements();) { 525 DatabaseField foreignKeyField = (DatabaseField)foreignKeysEnum.nextElement(); 526 getDescriptor().buildField(foreignKeyField); 527 } 528 529 if (!(getTargetToSourceKeyFields().isEmpty() && getSourceToTargetKeyFields().isEmpty())) { 531 if (getTargetToSourceKeyFields().isEmpty() || getSourceToTargetKeyFields().isEmpty()) { 532 initializeForeignKeysWithDefaults(session); 533 } else { 534 initializeForeignKeys(session); 535 } 536 } 537 538 if (shouldInitializeSelectionCriteria()) { 539 initializeSelectionCriteria(session); 540 } else { 541 setShouldVerifyDelete(false); 542 } 543 544 setFields(collectFields()); 545 } 546 547 551 protected void initializeForeignKeys(AbstractSession session) { 552 Iterator sourceEnum = getSourceToTargetKeyFields().keySet().iterator(); 553 Iterator targetEnum = getTargetToSourceKeyFields().keySet().iterator(); 554 while (sourceEnum.hasNext()) { 555 DatabaseField sourceField = (DatabaseField)sourceEnum.next(); 556 DatabaseField targetField = (DatabaseField)targetEnum.next(); 557 558 getDescriptor().buildField(sourceField); 559 getReferenceDescriptor().buildField(targetField); 560 } 561 } 562 563 567 protected void initializeForeignKeysWithDefaults(AbstractSession session) { 568 if (isForeignKeyRelationship()) { 569 if (getSourceToTargetKeyFields().size() != 1) { 570 throw DescriptorException.foreignKeysDefinedIncorrectly(this); 571 } 572 List targetKeys = getReferenceDescriptor().getPrimaryKeyFields(); 573 if (targetKeys.size() != 1) { 574 throw DescriptorException.sizeMismatchOfForeignKeys(this); 576 } 577 578 DatabaseField sourceField = (DatabaseField)getSourceToTargetKeyFields().keySet().iterator().next(); 580 getDescriptor().buildField(sourceField); 581 getSourceToTargetKeyFields().put(sourceField, targetKeys.get(0)); 582 getTargetToSourceKeyFields().put(targetKeys.get(0), sourceField); 583 } else { 584 if (getTargetToSourceKeyFields().size() != 1) { 585 throw DescriptorException.foreignKeysDefinedIncorrectly(this); 586 } 587 List sourceKeys = getDescriptor().getPrimaryKeyFields(); 588 if (sourceKeys.size() != 1) { 589 throw DescriptorException.sizeMismatchOfForeignKeys(this); 591 } 592 593 DatabaseField targetField = (DatabaseField)getTargetToSourceKeyFields().keySet().iterator().next(); 595 getReferenceDescriptor().buildField(targetField); 596 getTargetToSourceKeyFields().put(targetField, sourceKeys.get(0)); 597 getSourceToTargetKeyFields().put(sourceKeys.get(0), targetField); 598 } 599 } 600 601 605 protected void initializePrivateOwnedCriteria() { 606 if (!isForeignKeyRelationship()) { 607 setPrivateOwnedCriteria(getSelectionCriteria()); 608 } else { 609 Expression pkCriteria = getDescriptor().getObjectBuilder().getPrimaryKeyExpression(); 610 ExpressionBuilder builder = new ExpressionBuilder(); 611 Expression backRef = builder.getManualQueryKey(getAttributeName() + "-back-ref", getDescriptor()); 612 Expression newPKCriteria = pkCriteria.rebuildOn(backRef); 613 Expression twistedSelection = backRef.twist(getSelectionCriteria(), builder); 614 if (getDescriptor().getQueryManager().getAdditionalJoinExpression() != null) { 615 Expression rebuiltAdditional = getDescriptor().getQueryManager().getAdditionalJoinExpression().rebuildOn(backRef); 618 if (twistedSelection == null) { 619 twistedSelection = rebuiltAdditional; 620 } else { 621 twistedSelection = twistedSelection.and(rebuiltAdditional); 622 } 623 } 624 setPrivateOwnedCriteria(newPKCriteria.and(twistedSelection)); 625 } 626 } 627 628 636 protected void initializeSelectionCriteria(AbstractSession session) { 637 if (getSourceToTargetKeyFields().isEmpty()) { 638 throw DescriptorException.noForeignKeysAreSpecified(this); 639 } 640 641 Expression criteria; 642 Expression builder = new ExpressionBuilder(); 643 for (Iterator entries = getSourceToTargetKeyFields().entrySet().iterator(); entries.hasNext();) { 644 Map.Entry entry = (Map.Entry) entries.next(); 645 DatabaseField foreignKey = (DatabaseField)entry.getKey(); 646 DatabaseField targetKey = (DatabaseField)entry.getValue(); 647 Expression expression = builder.getField(targetKey).equal(builder.getParameter(foreignKey)); 648 criteria = expression.and(getSelectionCriteria()); 649 setSelectionCriteria(criteria); 650 } 651 } 652 653 661 public Expression buildSelectionCriteria() { 662 if (getSourceToTargetKeyFields().isEmpty()) { 664 throw DescriptorException.noForeignKeysAreSpecified(this); 665 } 666 667 Expression criteria = null; 668 Expression builder = new ExpressionBuilder(); 669 670 for (Iterator keys = getSourceToTargetKeyFields().keySet().iterator(); keys.hasNext();) { 671 DatabaseField foreignKey = (DatabaseField)keys.next(); 672 DatabaseField targetKey = (DatabaseField)getSourceToTargetKeyFields().get(foreignKey); 673 674 Expression expression = builder.getField(targetKey).equal(builder.getParameter(foreignKey)); 675 if (criteria == null) { 676 criteria = expression; 677 } else { 678 criteria = expression.and(criteria); 679 } 680 } 681 return criteria; 682 } 683 684 691 public void buildShallowOriginalFromRow(AbstractRecord databaseRow, Object original, ObjectBuildingQuery query, AbstractSession executionSession) { 692 ClassDescriptor descriptor = getReferenceDescriptor(); 699 AbstractRecord targetRow = new DatabaseRecord(); 700 701 for (Iterator keys = getSourceToTargetKeyFields().keySet().iterator(); keys.hasNext();) { 702 DatabaseField foreignKey = (DatabaseField)keys.next(); 703 DatabaseField targetKey = (DatabaseField)getSourceToTargetKeyFields().get(foreignKey); 704 705 targetRow.put(targetKey, databaseRow.get(foreignKey)); 706 } 707 708 Object targetObject = descriptor.getObjectBuilder().buildNewInstance(); 709 descriptor.getObjectBuilder().buildAttributesIntoShallowObject(targetObject, databaseRow, query); 710 targetObject = getIndirectionPolicy().valueFromRow(targetObject); 711 712 setAttributeValueInObject(original, targetObject); 713 } 714 715 718 public boolean isOneToOneMapping() { 719 return true; 720 } 721 722 726 protected Object readPrivateOwnedForObject(ObjectLevelModifyQuery modifyQuery) throws DatabaseException { 727 if (modifyQuery.getSession().isUnitOfWork()) { 728 return super.readPrivateOwnedForObject(modifyQuery); 729 } else { 730 if (!shouldVerifyDelete()) { 731 return null; 732 } 733 ReadObjectQuery readQuery = (ReadObjectQuery)getSelectionQuery().clone(); 734 735 readQuery.setSelectionCriteria(getPrivateOwnedCriteria()); 736 return modifyQuery.getSession().executeQuery(readQuery, modifyQuery.getTranslationRow()); 737 } 738 } 739 740 746 public void rehashFieldDependancies(AbstractSession session) { 747 setSourceToTargetKeyFields(Helper.rehashMap(getSourceToTargetKeyFields())); 748 } 749 750 762 public void setForeignKeyFieldName(String sourceForeignKeyFieldName) { 763 DatabaseField sourceField = new DatabaseField(sourceForeignKeyFieldName); 764 765 setIsForeignKeyRelationship(true); 766 getForeignKeyFields().addElement(sourceField); 767 getSourceToTargetKeyFields().put(sourceField, new DatabaseField()); 768 } 769 770 775 public void setForeignKeyFieldNames(Vector fieldNames) { 776 Vector fields = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(fieldNames.size()); 777 for (Enumeration fieldNamesEnum = fieldNames.elements(); fieldNamesEnum.hasMoreElements();) { 778 fields.addElement(new DatabaseField((String )fieldNamesEnum.nextElement())); 779 } 780 781 setForeignKeyFields(fields); 782 } 783 784 790 protected void setPrivateOwnedCriteria(Expression expression) { 791 privateOwnedCriteria = expression; 792 } 793 794 801 public void setShouldVerifyDelete(boolean shouldVerifyDelete) { 802 this.shouldVerifyDelete = shouldVerifyDelete; 803 } 804 805 809 public void setSourceToTargetKeyFieldAssociations(Vector sourceToTargetKeyFieldAssociations) { 810 setSourceToTargetKeyFields(new HashMap(sourceToTargetKeyFieldAssociations.size() + 1)); 811 setTargetToSourceKeyFields(new HashMap(sourceToTargetKeyFieldAssociations.size() + 1)); 812 for (Enumeration associationsEnum = sourceToTargetKeyFieldAssociations.elements(); 813 associationsEnum.hasMoreElements();) { 814 Association association = (Association)associationsEnum.nextElement(); 815 Object sourceField = new DatabaseField((String )association.getKey()); 816 Object targetField = new DatabaseField((String )association.getValue()); 817 getSourceToTargetKeyFields().put(sourceField, targetField); 818 getTargetToSourceKeyFields().put(targetField, sourceField); 819 } 820 } 821 822 826 public void setSourceToTargetKeyFields(Map sourceToTargetKeyFields) { 827 this.sourceToTargetKeyFields = sourceToTargetKeyFields; 828 } 829 830 842 public void setTargetForeignKeyFieldName(String targetForeignKeyFieldName) { 843 DatabaseField targetField = new DatabaseField(targetForeignKeyFieldName); 844 getTargetToSourceKeyFields().put(targetField, new DatabaseField()); 845 } 846 847 851 public void setTargetToSourceKeyFields(Map targetToSourceKeyFields) { 852 this.targetToSourceKeyFields = targetToSourceKeyFields; 853 } 854 855 861 public void setUsesJoining(boolean usesJoining) { 862 if (usesJoining == this.usesJoining) { 863 return; 864 } 865 this.usesJoining = usesJoining; 866 867 if (getDescriptor() != null) { 874 getDescriptor().reInitializeJoinedAttributes(); 875 } 876 877 } 880 881 887 public boolean shouldUseJoining() { 888 return usesJoining; 889 } 890 891 896 public boolean shouldVerifyDelete() { 897 return shouldVerifyDelete; 898 } 899 900 904 public boolean isCascadedLockingSupported() { 905 return true; 906 } 907 908 912 public boolean isJoiningSupported() { 913 return true; 914 } 915 916 922 public void useJoining() { 923 setUsesJoining(true); 924 } 925 926 931 public void writeFromAttributeIntoRow(Object attribute, AbstractRecord row, AbstractSession session) 932 { 933 for (Enumeration fieldsEnum = getForeignKeyFields().elements(); fieldsEnum.hasMoreElements();) { 934 DatabaseField sourceKey = (DatabaseField) fieldsEnum.nextElement(); 935 DatabaseField targetKey = (DatabaseField) getSourceToTargetKeyFields().get(sourceKey); 936 Object referenceValue = null; 937 if (attribute != null) { 939 referenceValue = getReferenceDescriptor().getObjectBuilder().extractValueFromObjectForField(attribute, targetKey, session); 940 } 941 row.add(sourceKey, referenceValue); 942 } 943 } 944 945 949 public Object valueFromObject(Object object, DatabaseField field, AbstractSession session) { 950 AbstractRecord referenceRow = getIndirectionPolicy().extractReferenceRow(getAttributeValueFromObject(object)); 952 if (referenceRow != null) { 953 Object value = referenceRow.get(field); 954 955 try { 957 value = session.getDatasourcePlatform().convertObject(value, getFieldClassification(field)); 958 } catch (ConversionException e) { 959 throw ConversionException.couldNotBeConverted(this, getDescriptor(), e); 960 } 961 return value; 962 } 963 964 Object referenceObject = getRealAttributeValueFromObject(object, session); 965 if (referenceObject == null) { 966 return null; 967 } 968 DatabaseField targetField = (DatabaseField)getSourceToTargetKeyFields().get(field); 969 970 return getReferenceDescriptor().getObjectBuilder().extractValueFromObjectForField(referenceObject, targetField, session); 971 } 972 973 977 protected Object valueFromRowInternalWithJoin(AbstractRecord row, JoinedAttributeManager joinManager, AbstractSession executionSession) throws DatabaseException { 978 Object referenceObject; 980 AbstractRecord targetRow = trimRowForJoin(row, joinManager, executionSession); 984 if (joinManager.isAttributeJoined(getDescriptor(), getAttributeName()) && joinManager.hasOuterJoinedAttributeQuery()) { 986 Vector key = this.referenceDescriptor.getObjectBuilder().extractPrimaryKeyFromRow(targetRow, executionSession); 987 if (key == null) { 988 return this.indirectionPolicy.nullValueFromRow(); 989 } 990 } 991 ObjectLevelReadQuery nestedQuery = null; 994 if (joinManager.getJoinedMappingQueries_() != null) { 995 nestedQuery = (ObjectLevelReadQuery) joinManager.getJoinedMappingQueries_().get(this); 996 } else { 997 nestedQuery = prepareNestedJoins(joinManager, executionSession); 998 } 999 nestedQuery = (ObjectLevelReadQuery)nestedQuery.clone(); 1000 nestedQuery.setTranslationRow(targetRow); 1001 nestedQuery.setSession(executionSession); 1002 nestedQuery.setQueryId(joinManager.getBaseQuery().getQueryId()); 1004 referenceObject = this.referenceDescriptor.getObjectBuilder().buildObject(nestedQuery, targetRow, nestedQuery.getJoinedAttributeManager()); 1005 1006 if (nestedQuery.shouldUseWrapperPolicy() && nestedQuery.getSession().isUnitOfWork()) { 1009 referenceObject = this.referenceDescriptor.getObjectBuilder().wrapObject(referenceObject, nestedQuery.getSession()); 1010 } 1011 return this.indirectionPolicy.valueFromRow(referenceObject); 1012 } 1013 1014 1019 protected Object valueFromRowInternal(AbstractRecord row, JoinedAttributeManager joinManager, AbstractSession executionSession) throws DatabaseException { 1020 int size = this.fields.size(); 1023 for (int index = 0; index < size; index++) { 1024 DatabaseField field = (DatabaseField)this.fields.get(index); 1025 if (row.get(field) == null) { 1026 return this.indirectionPolicy.nullValueFromRow(); 1027 } 1028 } 1029 1030 return super.valueFromRowInternal(row, joinManager, executionSession); 1033 } 1034 1035 1039 public void writeFromObjectIntoRow(Object object, AbstractRecord databaseRow, AbstractSession session) { 1040 if (isReadOnly() || (!isForeignKeyRelationship())) { 1041 return; 1042 } 1043 1044 AbstractRecord referenceRow = getIndirectionPolicy().extractReferenceRow(getAttributeValueFromObject(object)); 1045 if (referenceRow == null) { 1046 Object referenceObject = getRealAttributeValueFromObject(object, session); 1048 1049 for (Enumeration fieldsEnum = getForeignKeyFields().elements(); 1050 fieldsEnum.hasMoreElements();) { 1051 DatabaseField sourceKey = (DatabaseField)fieldsEnum.nextElement(); 1052 DatabaseField targetKey = (DatabaseField)getSourceToTargetKeyFields().get(sourceKey); 1053 1054 Object referenceValue = null; 1055 1056 if (referenceObject != null) { 1058 referenceValue = getReferenceDescriptor().getObjectBuilder().extractValueFromObjectForField(referenceObject, targetKey, session); 1059 } 1060 databaseRow.add(sourceKey, referenceValue); 1061 } 1062 } else { 1063 for (Enumeration fieldsEnum = getForeignKeyFields().elements(); 1064 fieldsEnum.hasMoreElements();) { 1065 DatabaseField sourceKey = (DatabaseField)fieldsEnum.nextElement(); 1066 Object referenceValue = referenceRow.get(sourceKey); 1067 databaseRow.add(sourceKey, referenceValue); 1068 } 1069 } 1070 } 1071 1072 1077 public void writeFromObjectIntoRowForShallowInsert(Object object, AbstractRecord databaseRow, AbstractSession session) { 1078 if (isReadOnly() || (!isForeignKeyRelationship())) { 1079 return; 1080 } 1081 1082 for (Enumeration fieldsEnum = getForeignKeyFields().elements(); 1083 fieldsEnum.hasMoreElements();) { 1084 DatabaseField sourceKey = (DatabaseField)fieldsEnum.nextElement(); 1085 databaseRow.add(sourceKey, null); 1086 } 1087 } 1088 1089 1093 public void writeFromObjectIntoRowWithChangeRecord(ChangeRecord changeRecord, AbstractRecord databaseRow, AbstractSession session) { 1094 if (isReadOnly() || (!isForeignKeyRelationship())) { 1095 return; 1096 } 1097 1098 Object object = ((ObjectChangeSet)changeRecord.getOwner()).getUnitOfWorkClone(); 1101 AbstractRecord referenceRow = getIndirectionPolicy().extractReferenceRow(getAttributeValueFromObject(object)); 1102 if (referenceRow == null) { 1103 Object referenceObject = getRealAttributeValueFromObject(object, session); 1105 1106 for (Enumeration fieldsEnum = getForeignKeyFields().elements(); 1107 fieldsEnum.hasMoreElements();) { 1108 DatabaseField sourceKey = (DatabaseField)fieldsEnum.nextElement(); 1109 DatabaseField targetKey = (DatabaseField)getSourceToTargetKeyFields().get(sourceKey); 1110 1111 Object referenceValue = null; 1112 1113 if (referenceObject != null) { 1115 referenceValue = getReferenceDescriptor().getObjectBuilder().extractValueFromObjectForField(referenceObject, targetKey, session); 1116 } 1117 databaseRow.add(sourceKey, referenceValue); 1118 } 1119 } else { 1120 for (Enumeration fieldsEnum = getForeignKeyFields().elements(); 1121 fieldsEnum.hasMoreElements();) { 1122 DatabaseField sourceKey = (DatabaseField)fieldsEnum.nextElement(); 1123 Object referenceValue = referenceRow.get(sourceKey); 1124 databaseRow.add(sourceKey, referenceValue); 1125 } 1126 } 1127 } 1128 1129 1134 public void writeFromObjectIntoRowForShallowInsertWithChangeRecord(ChangeRecord ChangeRecord, AbstractRecord databaseRow, AbstractSession session) { 1135 if (isReadOnly() || (!isForeignKeyRelationship())) { 1136 return; 1137 } 1138 1139 for (Enumeration fieldsEnum = getForeignKeyFields().elements(); 1140 fieldsEnum.hasMoreElements();) { 1141 DatabaseField sourceKey = (DatabaseField)fieldsEnum.nextElement(); 1142 databaseRow.add(sourceKey, null); 1143 } 1144 } 1145 1146 1150 public void writeInsertFieldsIntoRow(AbstractRecord databaseRow, AbstractSession session) { 1151 if (isReadOnly() || (!isForeignKeyRelationship())) { 1152 return; 1153 } 1154 1155 for (Enumeration fieldsEnum = getForeignKeyFields().elements(); 1156 fieldsEnum.hasMoreElements();) { 1157 DatabaseField sourceKey = (DatabaseField)fieldsEnum.nextElement(); 1158 databaseRow.add(sourceKey, null); 1159 } 1160 } 1161} 1162 | Popular Tags |