Skip to content

Commit c6e5bb3

Browse files
committed
Issue 1815: Transforming object types for collections
Signed-off-by: Will Dazey <[email protected]>
1 parent 2be887a commit c6e5bb3

File tree

3 files changed

+214
-35
lines changed

3 files changed

+214
-35
lines changed

foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/expressions/CollectionExpression.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,33 @@ public CollectionExpression(Object newValue, Expression baseExpression) {
3838

3939
@Override
4040
public void printSQL(ExpressionSQLPrinter printer) {
41-
Object value = this.value;
41+
Object objectValue = this.value;
4242
if(this.localBase != null) {
43-
value = this.localBase.getFieldValue(value, getSession());
43+
if(objectValue instanceof Collection) {
44+
Collection<?> values = (Collection<?>)objectValue;
45+
Vector<Object> fieldValues = new Vector<>(values.size());
46+
for (Object value : values) {
47+
Object translated = value;
48+
if (!(value instanceof Expression)){
49+
translated = this.localBase.getFieldValue(value, getSession());
50+
}
51+
fieldValues.add(translated);
52+
}
53+
objectValue = fieldValues;
54+
}
4455
}
45-
printer.printList((Collection)value, this.canBind);
56+
printer.printList((Collection)objectValue, this.canBind);
4657
}
4758

59+
// @Override
60+
// public void printSQL(ExpressionSQLPrinter printer) {
61+
// Object value = this.value;
62+
// if(this.localBase != null) {
63+
// value = this.localBase.getFieldValue(value, getSession());
64+
// }
65+
// printer.printList((Collection)value, this.canBind);
66+
// }
67+
4868
/**
4969
* INTERNAL:
5070
* Return the value for in memory comparison.

foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/expressions/ParameterExpression.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.Collection;
2323
import java.util.List;
2424
import java.util.Map;
25+
import java.util.Vector;
2526

2627
import org.eclipse.persistence.descriptors.ClassDescriptor;
2728
import org.eclipse.persistence.exceptions.QueryException;
@@ -320,6 +321,24 @@ public Object getValue(AbstractRecord translationRow, DatabaseQuery query, Abstr
320321
value = this.localBase.getFieldValue(value, session);
321322
}
322323

324+
// // Convert the value to the correct type, i.e. object type mappings.
325+
// if (this.localBase != null) {
326+
// if(value instanceof Collection) {
327+
// Collection<?> values = (Collection<?>)value;
328+
// Vector<Object> fieldValues = new Vector<>(values.size());
329+
// for (Object v : values) {
330+
// Object translated = v;
331+
// if (!(v instanceof Expression)){
332+
// translated = this.localBase.getFieldValue(v, getSession());
333+
// }
334+
// fieldValues.add(translated);
335+
// }
336+
// value = fieldValues;
337+
// } else {
338+
// value = this.localBase.getFieldValue(value, session);
339+
// }
340+
// }
341+
323342
return value;
324343
}
325344

foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/expressions/QueryKeyExpression.java

Lines changed: 172 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
2-
* Copyright (c) 1998, 2022 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2023 IBM Corporation. All rights reserved.
34
*
45
* This program and the accompanying materials are made available under the
56
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -414,6 +415,57 @@ public List<DatabaseField> getSelectionFields(ReadQuery query) {
414415
}
415416
}
416417

418+
// /**
419+
// * INTERNAL:
420+
// * Transform the object-level value into a database-level value
421+
// */
422+
// @Override
423+
// public Object getFieldValue(Object objectValue, AbstractSession session) {
424+
// DatabaseMapping mapping = getMapping();
425+
// Object fieldValue = objectValue;
426+
// if (mapping != null) {
427+
// if (mapping.isAbstractDirectMapping() || mapping.isDirectCollectionMapping()) {
428+
// // CR#3623207, check for IN Collection here not in mapping.
429+
// if (objectValue instanceof Collection) {
430+
// // This can actually be a collection for IN within expressions... however it would be better for expressions to handle this.
431+
// Collection values = (Collection)objectValue;
432+
// Vector fieldValues = new Vector(values.size());
433+
// for (Iterator iterator = values.iterator(); iterator.hasNext();) {
434+
// Object value = iterator.next();
435+
// if (!(value instanceof Expression)){
436+
// value = getFieldValue(value, session);
437+
// }
438+
// fieldValues.add(value);
439+
// }
440+
// fieldValue = fieldValues;
441+
// } else {
442+
// if (mapping.isAbstractColumnMapping()) {
443+
// fieldValue = ((AbstractColumnMapping)mapping).getFieldValue(objectValue, session);
444+
// } else if (mapping.isDirectCollectionMapping()) {
445+
// fieldValue = ((DirectCollectionMapping)mapping).getFieldValue(objectValue, session);
446+
// }
447+
// }
448+
// } else if ((objectValue instanceof Collection) && (mapping.isForeignReferenceMapping())) {
449+
// // Was an IN with a collection of objects, extract their ids.
450+
// List ids = new ArrayList();
451+
// for (Object object : ((Collection)objectValue)) {
452+
// if ((mapping.getReferenceDescriptor() != null) && (mapping.getReferenceDescriptor().getJavaClass().isInstance(object))) {
453+
// Object id = mapping.getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(object, session);
454+
// if (id instanceof CacheId) {
455+
// id = Arrays.asList(((CacheId)id).getPrimaryKey());
456+
// }
457+
// ids.add(id);
458+
// } else {
459+
// ids.add(object);
460+
// }
461+
// }
462+
// fieldValue = ids;
463+
// }
464+
// }
465+
//
466+
// return fieldValue;
467+
// }
468+
417469
/**
418470
* INTERNAL:
419471
* Transform the object-level value into a database-level value
@@ -424,47 +476,135 @@ public Object getFieldValue(Object objectValue, AbstractSession session) {
424476
Object fieldValue = objectValue;
425477
if (mapping != null) {
426478
if (mapping.isAbstractDirectMapping() || mapping.isDirectCollectionMapping()) {
427-
// CR#3623207, check for IN Collection here not in mapping.
428-
if (objectValue instanceof Collection) {
429-
// This can actually be a collection for IN within expressions... however it would be better for expressions to handle this.
430-
Collection values = (Collection)objectValue;
431-
Vector fieldValues = new Vector(values.size());
432-
for (Iterator iterator = values.iterator(); iterator.hasNext();) {
433-
Object value = iterator.next();
434-
if (!(value instanceof Expression)){
435-
value = getFieldValue(value, session);
436-
}
437-
fieldValues.add(value);
438-
}
439-
fieldValue = fieldValues;
440-
} else {
441-
if (mapping.isAbstractColumnMapping()) {
442-
fieldValue = ((AbstractColumnMapping)mapping).getFieldValue(objectValue, session);
443-
} else if (mapping.isDirectCollectionMapping()) {
444-
fieldValue = ((DirectCollectionMapping)mapping).getFieldValue(objectValue, session);
445-
}
479+
if (mapping.isAbstractColumnMapping()) {
480+
fieldValue = ((AbstractColumnMapping)mapping).getFieldValue(objectValue, session);
481+
} else if (mapping.isDirectCollectionMapping()) {
482+
fieldValue = ((DirectCollectionMapping)mapping).getFieldValue(objectValue, session);
446483
}
447484
} else if ((objectValue instanceof Collection) && (mapping.isForeignReferenceMapping())) {
448-
// Was an IN with a collection of objects, extract their ids.
449-
List ids = new ArrayList();
450-
for (Object object : ((Collection)objectValue)) {
451-
if ((mapping.getReferenceDescriptor() != null) && (mapping.getReferenceDescriptor().getJavaClass().isInstance(object))) {
452-
Object id = mapping.getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(object, session);
453-
if (id instanceof CacheId) {
454-
id = Arrays.asList(((CacheId)id).getPrimaryKey());
455-
}
456-
ids.add(id);
457-
} else {
458-
ids.add(object);
485+
if ((mapping.getReferenceDescriptor() != null) && (mapping.getReferenceDescriptor().getJavaClass().isInstance(objectValue))) {
486+
Object id = mapping.getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(objectValue, session);
487+
if (id instanceof CacheId) {
488+
id = Arrays.asList(((CacheId)id).getPrimaryKey());
459489
}
490+
fieldValue = id;
460491
}
461-
fieldValue = ids;
462492
}
463493
}
464494

465495
return fieldValue;
466496
}
467497

498+
// /**
499+
// * INTERNAL:
500+
// * Transform the object-level value into a database-level value
501+
// */
502+
// @Override
503+
// public Object getFieldValue(Object objectValue, AbstractSession session) {
504+
// DatabaseMapping mapping = getMapping();
505+
// Object fieldValue = objectValue;
506+
// if (mapping != null) {
507+
// if (mapping.isAbstractDirectMapping() || mapping.isDirectCollectionMapping()) {
508+
//
509+
//// if (objectValue instanceof Collection<?>) {
510+
//// // This can actually be a collection for IN within expressions... however it would be better for expressions to handle this.
511+
//// Collection<?> values = (Collection<?>)objectValue;
512+
////
513+
//// if(values.size() > 0 && ) {
514+
////
515+
//// }
516+
////
517+
//// Vector<Object> fieldValues = new Vector<>(values.size());
518+
//// Class<?> cls = mapping.getAttributeClassification();
519+
////
520+
//// for (Object value : values) {
521+
//// // If the element isn't the correct type
522+
//// if(cls != null && !cls.isAssignableFrom(value.getClass())) {
523+
//// value = getFieldValue(value, session);
524+
//// } else if (!(value instanceof Expression)){
525+
//// value = getFieldValue(value, session);
526+
//// }
527+
//// fieldValues.add(value);
528+
//// }
529+
//// fieldValue = fieldValues;
530+
//// } else {
531+
//// if (mapping.isAbstractColumnMapping()) {
532+
//// fieldValue = ((AbstractColumnMapping)mapping).getFieldValue(objectValue, session);
533+
//// } else if (mapping.isDirectCollectionMapping()) {
534+
//// fieldValue = ((DirectCollectionMapping)mapping).getFieldValue(objectValue, session);
535+
//// }
536+
//// }
537+
//
538+
// Class<?> cls = mapping.getAttributeClassification();
539+
//
540+
// // CR#3623207, check for IN Collection here not in mapping.
541+
// // Translate the individual elements of a collection to match the mapping type. This is important for IN collections
542+
// // However, only translate the elements if the mapping is not to a collection itself. Otherwise, we want to maintain a Collection for serialization
543+
// if(objectValue instanceof Collection<?> && cls != null && !cls.isAssignableFrom(objectValue.getClass())) {
544+
// // This can actually be a collection for IN within expressions... however it would be better for expressions to handle this.
545+
// Collection<?> values = (Collection<?>)objectValue;
546+
// Vector<Object> fieldValues = new Vector<>(values.size());
547+
// for (Iterator<?> iterator = values.iterator(); iterator.hasNext();) {
548+
// Object value = iterator.next();
549+
// if (!(value instanceof Expression)) {
550+
// if (mapping.isAbstractColumnMapping()) {
551+
// value = ((AbstractColumnMapping)mapping).getFieldValue(value, session);
552+
// } else if (mapping.isDirectCollectionMapping()) {
553+
// value = ((DirectCollectionMapping)mapping).getFieldValue(value, session);
554+
// }
555+
// }
556+
// fieldValues.add(value);
557+
// }
558+
// fieldValue = fieldValues;
559+
// } else {
560+
// if (mapping.isAbstractColumnMapping()) {
561+
// fieldValue = ((AbstractColumnMapping)mapping).getFieldValue(objectValue, session);
562+
// } else if (mapping.isDirectCollectionMapping()) {
563+
// fieldValue = ((DirectCollectionMapping)mapping).getFieldValue(objectValue, session);
564+
// }
565+
// }
566+
//
567+
//// if (objectValue instanceof Collection
568+
//// && (cls != null && !(cls.isArray() || cls.isInstance(Collection.class)))) {
569+
//// // This can actually be a collection for IN within expressions... however it would be better for expressions to handle this.
570+
//// Collection<?> values = (Collection<?>)objectValue;
571+
//// Vector<Object> fieldValues = new Vector<>(values.size());
572+
//// for (Iterator<?> iterator = values.iterator(); iterator.hasNext();) {
573+
//// Object value = iterator.next();
574+
//// if (!(value instanceof Expression)){
575+
//// value = getFieldValue(value, session);
576+
//// }
577+
//// fieldValues.add(value);
578+
//// }
579+
//// fieldValue = fieldValues;
580+
//// } else {
581+
//// if (mapping.isAbstractColumnMapping()) {
582+
//// fieldValue = ((AbstractColumnMapping)mapping).getFieldValue(objectValue, session);
583+
//// } else if (mapping.isDirectCollectionMapping()) {
584+
//// fieldValue = ((DirectCollectionMapping)mapping).getFieldValue(objectValue, session);
585+
//// }
586+
//// }
587+
// } else if ((objectValue instanceof Collection<?>) && (mapping.isForeignReferenceMapping())) {
588+
// // Was an IN with a collection of objects, extract their ids.
589+
// List<Object> ids = new ArrayList<>();
590+
// for (Object object : ((Collection<?>)objectValue)) {
591+
// if ((mapping.getReferenceDescriptor() != null) && (mapping.getReferenceDescriptor().getJavaClass().isInstance(object))) {
592+
// Object id = mapping.getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(object, session);
593+
// if (id instanceof CacheId) {
594+
// id = Arrays.asList(((CacheId)id).getPrimaryKey());
595+
// }
596+
// ids.add(id);
597+
// } else {
598+
// ids.add(object);
599+
// }
600+
// }
601+
// fieldValue = ids;
602+
// }
603+
// }
604+
//
605+
// return fieldValue;
606+
// }
607+
468608
@Override
469609
public DatabaseMapping getMapping() {
470610
if (!hasMapping) {

0 commit comments

Comments
 (0)