|
Lines 33-39
Link Here
|
| 33 |
package org.eclipse.persistence.internal.jpa.metadata.accessors.mappings; |
33 |
package org.eclipse.persistence.internal.jpa.metadata.accessors.mappings; |
| 34 |
|
34 |
|
| 35 |
import java.util.ArrayList; |
35 |
import java.util.ArrayList; |
| 36 |
import java.util.HashSet; |
|
|
| 37 |
import java.util.List; |
36 |
import java.util.List; |
| 38 |
|
37 |
|
| 39 |
import javax.persistence.FetchType; |
38 |
import javax.persistence.FetchType; |
|
Lines 119-125
Link Here
|
| 119 |
if (isAnnotationPresent(MapsId.class)) { |
118 |
if (isAnnotationPresent(MapsId.class)) { |
| 120 |
// Call getAttributeString in this case because we rely on the |
119 |
// Call getAttributeString in this case because we rely on the |
| 121 |
// mapsId not being null and it's value of "" means we need to |
120 |
// mapsId not being null and it's value of "" means we need to |
| 122 |
// default. getAttribute returns null which kills (hasMapsId()) |
121 |
// default. getAttribute returns null which kills hasMapsId() logic |
| 123 |
m_mapsId = (String) getAnnotation(MapsId.class).getAttributeString("value"); |
122 |
m_mapsId = (String) getAnnotation(MapsId.class).getAttributeString("value"); |
| 124 |
} |
123 |
} |
| 125 |
|
124 |
|
|
Lines 129-134
Link Here
|
| 129 |
|
128 |
|
| 130 |
/** |
129 |
/** |
| 131 |
* INTERNAL: |
130 |
* INTERNAL: |
|
|
131 |
* Return true is this accessor is a derived id accessor. |
| 132 |
*/ |
| 133 |
@Override |
| 134 |
public boolean derivesId() { |
| 135 |
return hasId() || hasMapsId(); |
| 136 |
} |
| 137 |
|
| 138 |
/** |
| 139 |
* INTERNAL: |
| 132 |
* Return the default fetch type for an object mapping. |
140 |
* Return the default fetch type for an object mapping. |
| 133 |
*/ |
141 |
*/ |
| 134 |
public String getDefaultFetchType() { |
142 |
public String getDefaultFetchType() { |
|
Lines 208-213
Link Here
|
| 208 |
/** |
216 |
/** |
| 209 |
* INTERNAL: |
217 |
* INTERNAL: |
| 210 |
*/ |
218 |
*/ |
|
|
219 |
protected boolean hasId() { |
| 220 |
return m_id != null && m_id; |
| 221 |
} |
| 222 |
|
| 223 |
/** |
| 224 |
* INTERNAL: |
| 225 |
*/ |
| 211 |
protected boolean hasMapsId() { |
226 |
protected boolean hasMapsId() { |
| 212 |
return m_mapsId != null; |
227 |
return m_mapsId != null; |
| 213 |
} |
228 |
} |
|
Lines 223-229
Link Here
|
| 223 |
mapping.setIsOptional(isOptional()); |
238 |
mapping.setIsOptional(isOptional()); |
| 224 |
mapping.setAttributeName(getAttributeName()); |
239 |
mapping.setAttributeName(getAttributeName()); |
| 225 |
mapping.setReferenceClassName(getReferenceClassName()); |
240 |
mapping.setReferenceClassName(getReferenceClassName()); |
| 226 |
mapping.setIsDerivedIdMapping(isDerivedId()); |
241 |
mapping.setDerivesId(derivesId()); |
| 227 |
|
242 |
|
| 228 |
// Process the orphanRemoval or PrivateOwned |
243 |
// Process the orphanRemoval or PrivateOwned |
| 229 |
processOrphanRemoval(mapping); |
244 |
processOrphanRemoval(mapping); |
|
Lines 256-270
Link Here
|
| 256 |
|
271 |
|
| 257 |
/** |
272 |
/** |
| 258 |
* INTERNAL: |
273 |
* INTERNAL: |
| 259 |
* Return true is this accessor is a derived id accessor. |
|
|
| 260 |
*/ |
| 261 |
@Override |
| 262 |
public boolean isDerivedId() { |
| 263 |
return m_id != null && m_id; |
| 264 |
} |
| 265 |
|
| 266 |
/** |
| 267 |
* INTERNAL: |
| 268 |
* Return true if this accessor represents a 1-1 primary key relationship. |
274 |
* Return true if this accessor represents a 1-1 primary key relationship. |
| 269 |
*/ |
275 |
*/ |
| 270 |
public boolean isOneToOnePrimaryKeyRelationship() { |
276 |
public boolean isOneToOnePrimaryKeyRelationship() { |
|
Lines 329-390
Link Here
|
| 329 |
|
335 |
|
| 330 |
/** |
336 |
/** |
| 331 |
* INTERNAL: |
337 |
* INTERNAL: |
| 332 |
* Process the indirection (aka fetch type) |
|
|
| 333 |
*/ |
| 334 |
protected void processIndirection(ObjectReferenceMapping mapping) { |
| 335 |
boolean usesIndirection = usesIndirection(); |
| 336 |
|
| 337 |
// If weaving was disabled, and the class was not static weaved, |
| 338 |
// then disable indirection. |
| 339 |
if (usesIndirection && (!getProject().isWeavingEnabled()) |
| 340 |
&& (!ClassConstants.PersistenceWeavedLazy_Class.isAssignableFrom(getJavaClass(getDescriptor().getJavaClass())))) { |
| 341 |
usesIndirection = false; |
| 342 |
} |
| 343 |
|
| 344 |
if (usesIndirection && usesPropertyAccess(getDescriptor())) { |
| 345 |
mapping.setIndirectionPolicy(new WeavedObjectBasicIndirectionPolicy(getSetMethodName())); |
| 346 |
} else { |
| 347 |
mapping.setUsesIndirection(usesIndirection); |
| 348 |
} |
| 349 |
|
| 350 |
mapping.setIsLazy(isLazy()); |
| 351 |
} |
| 352 |
|
| 353 |
/** |
| 354 |
* INTERNAL: |
| 355 |
* Used to process primary keys and DerivedIds. |
338 |
* Used to process primary keys and DerivedIds. |
| 356 |
*/ |
339 |
*/ |
| 357 |
public void processKey(HashSet<ClassAccessor> processing, HashSet<ClassAccessor> processed){ |
340 |
protected void processId(OneToOneMapping mapping) { |
|
|
341 |
// If this entity has a pk class, we need to validate our ids. |
| 358 |
MetadataDescriptor referenceDescriptor = getReferenceDescriptor(); |
342 |
MetadataDescriptor referenceDescriptor = getReferenceDescriptor(); |
| 359 |
ClassAccessor referenceAccessor = referenceDescriptor.getClassAccessor(); |
|
|
| 360 |
|
| 361 |
if (!processed.contains(referenceAccessor)){ |
| 362 |
referenceAccessor.processDerivedIDs(processing, processed); |
| 363 |
} |
| 364 |
|
| 365 |
processRelationship(); |
| 366 |
String attributeName = getAttributeName(); |
| 367 |
|
| 368 |
// If this entity has a pk class, we need to validate our ids. |
| 369 |
String keyname = referenceDescriptor.getPKClassName(); |
343 |
String keyname = referenceDescriptor.getPKClassName(); |
| 370 |
|
344 |
|
| 371 |
if (keyname != null) { |
345 |
if (keyname != null) { |
| 372 |
// They have a pk class |
346 |
// They have a pk class |
| 373 |
String ourpkname = this.getDescriptor().getPKClassName(); |
347 |
String ourpkname = getDescriptor().getPKClassName(); |
| 374 |
if (ourpkname == null){ |
348 |
if (ourpkname == null){ |
| 375 |
throw ValidationException.invalidCompositePKSpecification(getJavaClass(), ourpkname); |
349 |
throw ValidationException.invalidCompositePKSpecification(getJavaClass(), ourpkname); |
| 376 |
} |
350 |
} |
| 377 |
|
351 |
|
| 378 |
if (! ourpkname.equals(keyname)){ |
352 |
if (! ourpkname.equals(keyname)){ |
| 379 |
// Validate our pk contains their pk. |
353 |
// Validate our pk contains their pk. |
| 380 |
getOwningDescriptor().validatePKClassId(attributeName, referenceDescriptor.getPKClass()); |
354 |
getOwningDescriptor().validatePKClassId(getAttributeName(), referenceDescriptor.getPKClass()); |
| 381 |
} else { |
355 |
} else { |
| 382 |
// This pk is the reference pk, so all pk attributes are accounted through this relationship |
356 |
// This pk is the reference pk, so all pk attributes are accounted through this relationship |
| 383 |
getOwningDescriptor().getPKClassIDs().clear(); |
357 |
getOwningDescriptor().getPKClassIDs().clear(); |
| 384 |
} |
358 |
} |
| 385 |
} else { |
359 |
} else { |
| 386 |
MetadataClass type = null; |
360 |
MetadataClass type = null; |
| 387 |
if (referenceAccessor.hasDerivedId()){ |
361 |
if (referenceDescriptor.getClassAccessor().hasDerivedId()){ |
| 388 |
// Referenced object has a derived ID but no PK class defined, |
362 |
// Referenced object has a derived ID but no PK class defined, |
| 389 |
// so it must be a simple pk type. Recurse through to get the |
363 |
// so it must be a simple pk type. Recurse through to get the |
| 390 |
// simple type |
364 |
// simple type |
|
Lines 394-407
Link Here
|
| 394 |
type = referenceDescriptor.getAccessorFor(referenceDescriptor.getIdAttributeName()).getRawClass(); |
368 |
type = referenceDescriptor.getAccessorFor(referenceDescriptor.getIdAttributeName()).getRawClass(); |
| 395 |
} |
369 |
} |
| 396 |
|
370 |
|
| 397 |
getOwningDescriptor().validatePKClassId(attributeName, type); |
371 |
getOwningDescriptor().validatePKClassId(getAttributeName(), type); |
| 398 |
} |
372 |
} |
| 399 |
|
373 |
|
| 400 |
// Store the Id attribute name. Used with validation and OrderBy. |
374 |
// Store the Id attribute name. Used with validation and OrderBy. |
| 401 |
getOwningDescriptor().addIdAttributeName(attributeName); |
375 |
getOwningDescriptor().addIdAttributeName(getAttributeName()); |
| 402 |
|
376 |
|
| 403 |
// Add the primary key fields to the descriptor. |
377 |
// Add the primary key fields to the descriptor. |
| 404 |
ObjectReferenceMapping mapping = (ObjectReferenceMapping) getMapping(); |
|
|
| 405 |
for (DatabaseField pkField : mapping.getForeignKeyFields()) { |
378 |
for (DatabaseField pkField : mapping.getForeignKeyFields()) { |
| 406 |
getOwningDescriptor().addPrimaryKeyField(pkField, null); |
379 |
getOwningDescriptor().addPrimaryKeyField(pkField, null); |
| 407 |
} |
380 |
} |
|
Lines 409-414
Link Here
|
| 409 |
|
382 |
|
| 410 |
/** |
383 |
/** |
| 411 |
* INTERNAL: |
384 |
* INTERNAL: |
|
|
385 |
* Process the indirection (aka fetch type) |
| 386 |
*/ |
| 387 |
protected void processIndirection(ObjectReferenceMapping mapping) { |
| 388 |
boolean usesIndirection = usesIndirection(); |
| 389 |
|
| 390 |
// If weaving was disabled, and the class was not static weaved, |
| 391 |
// then disable indirection. |
| 392 |
if (usesIndirection && (!getProject().isWeavingEnabled()) |
| 393 |
&& (!ClassConstants.PersistenceWeavedLazy_Class.isAssignableFrom(getJavaClass(getDescriptor().getJavaClass())))) { |
| 394 |
usesIndirection = false; |
| 395 |
} |
| 396 |
|
| 397 |
if (usesIndirection && usesPropertyAccess(getDescriptor())) { |
| 398 |
mapping.setIndirectionPolicy(new WeavedObjectBasicIndirectionPolicy(getSetMethodName())); |
| 399 |
} else { |
| 400 |
mapping.setUsesIndirection(usesIndirection); |
| 401 |
} |
| 402 |
|
| 403 |
mapping.setIsLazy(isLazy()); |
| 404 |
} |
| 405 |
|
| 406 |
/** |
| 407 |
* INTERNAL: |
| 412 |
* Process the mapping keys from the maps id value. |
408 |
* Process the mapping keys from the maps id value. |
| 413 |
*/ |
409 |
*/ |
| 414 |
protected void processMapsId(OneToOneMapping oneToOneMapping) { |
410 |
protected void processMapsId(OneToOneMapping oneToOneMapping) { |
|
Lines 428-464
Link Here
|
| 428 |
|
424 |
|
| 429 |
// Set the primary key mapping as read only. |
425 |
// Set the primary key mapping as read only. |
| 430 |
primaryKeyMapping.setIsReadOnly(true); |
426 |
primaryKeyMapping.setIsReadOnly(true); |
| 431 |
} else if (embeddedIdAccessor.getReferenceClassName().equals(getReferenceDescriptor().getPKClassName())) { |
427 |
|
| 432 |
// Embedded id class is the same as the parents parents id class. |
428 |
// Set the maps id mapping. |
| 433 |
// Case #5: Parent uses id class == to dependent's embedded id class |
429 |
oneToOneMapping.setDerivedIdMapping(primaryKeyMapping); |
| 434 |
// Case #6: Both parent and dependent use same embedded id class. |
|
|
| 435 |
processMapsIdFields(oneToOneMapping, embeddedIdAccessor, null); |
| 436 |
} else { |
430 |
} else { |
| 437 |
if (m_mapsId.equals("")) { |
431 |
if (embeddedIdAccessor.getReferenceClassName().equals(getReferenceDescriptor().getPKClassName())) { |
| 438 |
// User didn't specify a mapsId value. By default the attribute name from this object accessor is used. |
432 |
// Embedded id class is the same as the parents parents id class. |
| 439 |
m_mapsId = getAttributeName(); |
433 |
// Case #5: Parent uses id class == to dependent's embedded id class |
| 440 |
} |
434 |
// Case #6: Both parent and dependent use same embedded id class. |
|
|
435 |
processMapsIdFields(oneToOneMapping, embeddedIdAccessor, null); |
| 436 |
} else { |
| 437 |
if (m_mapsId.equals("")) { |
| 438 |
// User didn't specify a mapsId value. By default the attribute name from this object accessor is used. |
| 439 |
m_mapsId = getAttributeName(); |
| 440 |
} |
| 441 |
|
441 |
|
| 442 |
MappingAccessor mappingAccessor = embeddedIdAccessor.getReferenceDescriptor().getAccessorFor(m_mapsId); |
442 |
MappingAccessor mappingAccessor = embeddedIdAccessor.getReferenceDescriptor().getAccessorFor(m_mapsId); |
| 443 |
|
443 |
|
| 444 |
if (mappingAccessor == null) { |
444 |
if (mappingAccessor == null) { |
| 445 |
throw ValidationException.invalidMappedByIdValue(m_mapsId, getAnnotatedElementName(), embeddedIdAccessor.getReferenceClass()); |
445 |
throw ValidationException.invalidMappedByIdValue(m_mapsId, getAnnotatedElementName(), embeddedIdAccessor.getReferenceClass()); |
| 446 |
} else if (mappingAccessor.isBasic()) { |
446 |
} else if (mappingAccessor.isBasic()) { |
| 447 |
// Case #1: basic mapping from embedded id to parent entity. |
447 |
// Case #1: basic mapping from embedded id to parent entity. |
| 448 |
processMapsIdFields(oneToOneMapping, embeddedIdAccessor, mappingAccessor); |
448 |
processMapsIdFields(oneToOneMapping, embeddedIdAccessor, mappingAccessor); |
| 449 |
} else if (mappingAccessor.isDerivedIdClass()) { |
449 |
} else if (mappingAccessor.isDerivedIdClass()) { |
| 450 |
// Case #2 and case #3 (Id class or embedded id used as the derived id) |
450 |
// Case #2 and case #3 (Id class or embedded id used as the derived id) |
| 451 |
processMapsIdFields(oneToOneMapping, (DerivedIdClassAccessor) mappingAccessor, null); |
451 |
processMapsIdFields(oneToOneMapping, (DerivedIdClassAccessor) mappingAccessor, null); |
|
|
452 |
} |
| 453 |
|
| 454 |
// Set the maps id value on the mapping. |
| 455 |
oneToOneMapping.setMapsIdValue(m_mapsId); |
| 452 |
} |
456 |
} |
| 453 |
|
457 |
|
| 454 |
// This will also set the isDerivedIdMapping flag to true. |
458 |
// Set the maps id mapping. |
| 455 |
oneToOneMapping.setMappedByIdValue(m_mapsId); |
459 |
oneToOneMapping.setDerivedIdMapping(embeddedIdAccessor.getMapping()); |
| 456 |
} |
460 |
} |
| 457 |
} |
461 |
} |
| 458 |
|
462 |
|
| 459 |
/** |
463 |
/** |
| 460 |
* INTERNAL: |
464 |
* INTERNAL: |
| 461 |
* We're going to field name translations where necessary. If the user |
465 |
* We're going to add field name translations where necessary. If the user |
| 462 |
* specified (erroneously that is) attribute overrides this will override |
466 |
* specified (erroneously that is) attribute overrides this will override |
| 463 |
* them. |
467 |
* them. |
| 464 |
* The embedded accessor passed in is either the root embedded id accessor |
468 |
* The embedded accessor passed in is either the root embedded id accessor |
|
Lines 571-581
Link Here
|
| 571 |
* a mapsId first. |
575 |
* a mapsId first. |
| 572 |
*/ |
576 |
*/ |
| 573 |
protected void processOwningMappingKeys(OneToOneMapping mapping) { |
577 |
protected void processOwningMappingKeys(OneToOneMapping mapping) { |
| 574 |
if (hasMapsId()) { |
578 |
if (derivesId()) { |
| 575 |
// We need to process the join columns as we normally would. |
579 |
// We need to process the join columns as we normally would. |
| 576 |
// Then we must update the fields from our derived id accessor. |
580 |
// Then we must update the fields from our derived id accessor. |
| 577 |
processOneToOneForeignKeyRelationship(mapping); |
581 |
processOneToOneForeignKeyRelationship(mapping); |
| 578 |
processMapsId(mapping); |
582 |
|
|
|
583 |
if (hasMapsId()) { |
| 584 |
processMapsId(mapping); |
| 585 |
} else { |
| 586 |
processId(mapping); |
| 587 |
} |
| 579 |
} else if (isOneToOnePrimaryKeyRelationship()) { |
588 |
} else if (isOneToOnePrimaryKeyRelationship()) { |
| 580 |
processOneToOnePrimaryKeyRelationship(mapping); |
589 |
processOneToOnePrimaryKeyRelationship(mapping); |
| 581 |
} else if (hasJoinTable()) { |
590 |
} else if (hasJoinTable()) { |