jodd-db/src/main/java/jodd/db/oom/JoinHintResolver.java
public Object[] join(final Object[] data, final String[] hints) {
		if (hints == null) {
			return data;
		}
		// build context
		Map<String, Object> context = new HashMap<>(hints.length);
		for (int i = 0; i < hints.length; i++) {
			hints[i] = hints[i].trim();
			String hint = hints[i];
			if (hint.indexOf('.') == -1) {
				context.put(hint, data[i]);
			}
		}

		// no joining hints found
		if (context.size() == data.length) {
			return data;
		}

		// joining
		Object[] result = new Object[context.size()];
		int count = 0;
		for (int i = 0; i < hints.length; i++) {

			String hint = hints[i];
			int ndx = hint.indexOf('.');
			if (ndx != -1) {
				String key = hint.substring(0, ndx);
				Object value = context.get(key);
				if (value == null) {
					throw new DbOomException("Hint value missing: " + key);
				}

				// don't merge nulls
				if (data[i] == null) {
					continue;
				}

				String hintPropertyName = hint.substring(ndx + 1);
				Class hintPropertyType = BeanUtil.pojo.getPropertyType(value, hintPropertyName);

				if (hintPropertyType != null) {
					ClassDescriptor cd = ClassIntrospector.get().lookup(hintPropertyType);

					if (cd.isCollection()) {
						// add element to collection
						try {
							Collection collection = BeanUtil.declared.getProperty(value, hintPropertyName);

							if (collection == null) {
								collection = (Collection) ClassUtil.newInstance(hintPropertyType);
								BeanUtil.declaredSilent.setProperty(value, hintPropertyName, collection);
							}

							collection.add(data[i]);
						} catch (Exception ex) {
							throw new DbOomException(ex);
						}
					} else if (cd.isArray()) {
						// add element to array
						try {
							Object[] array = BeanUtil.declared.getProperty(value, hintPropertyName);

							if (array == null) {
								array = (Object[]) Array.newInstance(hintPropertyType.getComponentType(), 1);

								BeanUtil.declaredSilent.setProperty(value, hintPropertyName, array);

								array[0] = data[i];
							} else {
								Object[] newArray = ArraysUtil.append(array, data[i]);

								if (newArray != array) {
									BeanUtil.declaredSilent.setProperty(value, hintPropertyName, newArray);
								}
							}
						} catch (Exception ex) {
							throw new DbOomException(ex);
						}
					} else {
						// set value
						BeanUtil.declaredSilent.setProperty(value, hintPropertyName, data[i]);
					}
				}
				else {
					// special case - the property probably contains the collection in the way

					int lastNdx = hintPropertyName.lastIndexOf('.');

					String name = hintPropertyName.substring(0, lastNdx);

					Object target = resolveValueInSpecialCase(value, name);

					if (target != null) {
						String targetSimpleName = hintPropertyName.substring(lastNdx + 1);

						BeanUtil.declaredForcedSilent.setProperty(target, targetSimpleName, data[i]);
					}
				}

			} else {
				result[count] = data[i];
				count++;
			}
		}
		return result;
	}
public Object[] join(final Object[] data, final String[] hints) {
		if (hints == null) {
			return data;
		}
		// build context
		Map<String, Object> context = new HashMap<>(hints.length);
		for (int i = 0; i < hints.length; i++) {
			hints[i] = hints[i].trim();
			String hint = hints[i];
			if (hint.indexOf('.') == -1) {
				context.put(hint, data[i]);
			}
		}

		// no joining hints found
		if (context.size() == data.length) {
			return data;
		}

		// joining
		Object[] result = new Object[context.size()];
		int count = 0;
		for (int i = 0; i < hints.length; i++) {

			String hint = hints[i];
			int ndx = hint.indexOf('.');
			if (ndx != -1) {
				String key = hint.substring(0, ndx);
				Object value = context.get(key);
				if (value == null) {
					throw new DbOomException("Hint value missing: " + key);
				}

				// don't merge nulls
				if (data[i] == null) {
					continue;
				}

				String hintPropertyName = hint.substring(ndx + 1);
				Class hintPropertyType = BeanUtil.pojo.getPropertyType(value, hintPropertyName);

				if (hintPropertyType != null) {
					ClassDescriptor cd = ClassIntrospector.get().lookup(hintPropertyType);

					if (cd.isCollection()) {
						// add element to collection
						try {
							Collection collection = BeanUtil.declared.getProperty(value, hintPropertyName);

							if (collection == null) {
								collection = (Collection) ClassUtil.newInstance(hintPropertyType);
								BeanUtil.declaredSilent.setProperty(value, hintPropertyName, collection);
							}

							collection.add(data[i]);
						} catch (Exception ex) {
							throw new DbOomException(ex);
						}
					} else if (cd.isArray()) {
						// add element to array
						try {
							Object[] array = BeanUtil.declared.getProperty(value, hintPropertyName);

							if (array == null) {
								array = (Object[]) Array.newInstance(hintPropertyType.getComponentType(), 1);

								BeanUtil.declaredSilent.setProperty(value, hintPropertyName, array);

								array[0] = data[i];
							} else {
								Object[] newArray = ArraysUtil.append(array, data[i]);

								if (newArray != array) {
									BeanUtil.declaredSilent.setProperty(value, hintPropertyName, newArray);
								}
							}
						} catch (Exception ex) {
							throw new DbOomException(ex);
						}
					} else {
						// set value
						BeanUtil.declaredSilent.setProperty(value, hintPropertyName, data[i]);
					}
				}
				else {
					// special case - the property probably contains the collection in the way

					int lastNdx = hintPropertyName.lastIndexOf('.');

					String name = hintPropertyName.substring(0, lastNdx);

					Object target = resolveValueInSpecialCase(value, name);

					if (target != null) {
						String targetSimpleName = hintPropertyName.substring(lastNdx + 1);

						BeanUtil.declaredForcedSilent.setProperty(target, targetSimpleName, data[i]);
					}
				}

			} else {
				result[count] = data[i];
				count++;
			}
		}
		return result;
	}
Joins entity array using provided string hints.