Skip to content

Commit

Permalink
MID-6319: fix of one-to-many mapping, key normalization was missing
Browse files Browse the repository at this point in the history
  • Loading branch information
virgo47 committed Jun 24, 2020
1 parent 37b957c commit fd2efeb
Showing 1 changed file with 14 additions and 4 deletions.
Expand Up @@ -33,6 +33,10 @@ public static void main(String[] args) throws Exception {
exporter.export(conn.getMetaData());
*/

examples();
}

private static void examples() {
System.out.println(M_AUDIT_EVENT);
System.out.println("\nColumns: " + M_AUDIT_EVENT.getColumns());
System.out.println("\nAnnotated element: " + M_AUDIT_EVENT.getAnnotatedElement());
Expand Down Expand Up @@ -66,7 +70,7 @@ public static void main(String[] args) throws Exception {
Map<?, ?> transform = query.transform(GroupBy.groupBy(M_AUDIT_EVENT.id).as(GroupBy.list(M_AUDIT_DELTA)));
System.out.println("transform = " + transform);

// "manual" transformation
// "manual" transformation of one-to-many to proper graph
List<Tuple> plainResult = queryFactory
.select(M_AUDIT_EVENT, M_AUDIT_DELTA)
.from(M_AUDIT_EVENT)
Expand All @@ -76,16 +80,19 @@ public static void main(String[] args) throws Exception {
// .orderBy(M_AUDIT_EVENT.id.asc())
.where(M_AUDIT_EVENT.id.eq(452L))
.fetch();
System.out.println("\nFinal result"
+ mapOneToMany(plainResult, M_AUDIT_EVENT, M_AUDIT_DELTA, (o, m) -> o.addDelta(m)));
Map<MAuditEventRecord, Collection<MAuditDelta>> resultMap =
mapOneToMany(plainResult, M_AUDIT_EVENT, M_AUDIT_DELTA, (o, m) -> o.addDelta(m));
System.out.println("\nFinal result" + resultMap);

System.out.println("deltas for 1st item: " + resultMap.keySet().iterator().next().deltas);
}

/**
* Resolves one-to-many relations between two paths from the {@link Tuple}-based result.
* Returns map with "one" entities as keys (preserving original order) and related "many"
* entities as a collection in the value for each key.
* Optional accumulator can call further processing on both objects for each "many" item.
*
* <p>
* Note that proper equals/hashCode must be implemented for {@code <O>} type.
*
* @param rawResult collection of tuples, unprocessed result
Expand All @@ -102,12 +109,15 @@ private static <O, M> Map<O, Collection<M>> mapOneToMany(
RelationalPathBase<M> manyPath,
@Nullable BiConsumer<O, M> manyAccumulator) {

Map<O, O> canonicalKey = new HashMap<>();
Map<O, Collection<M>> result = new LinkedHashMap<>();
for (Tuple row : rawResult) {
O oneItem = Objects.requireNonNull(row.get(onePath),
"result for path " + onePath + " not found in tuple " + row);
M manyItem = Objects.requireNonNull(row.get(manyPath),
"result for path " + manyPath + " not found in tuple " + row);

oneItem = canonicalKey.computeIfAbsent(oneItem, v -> v);
result.computeIfAbsent(oneItem, o -> new ArrayList<>())
.add(manyItem);

Expand Down

0 comments on commit fd2efeb

Please sign in to comment.