Проблема использования стандартного фильтра и view с fetch="JOIN"

Добрый день.

Столкнулся с проблемой использования стандартного фильтра (в экранах типа Browse) в которых сущность загружается с использование представления (view) в которых есть fetch=‘JOIN’.
Например имеет такие сущности:

public class Employee extends BaseIdentityIdEntity {
    ...
    @JoinColumn(name = "PERSON_ID")
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @NotNull
    private Person person;
    ...
}

public class Person extends BaseIdentityIdEntity {
    ...
    @Composition
    @OnDelete(DeletePolicy.CASCADE)
    @OneToMany(mappedBy = "person")
    private List<PersonNames> personNamesList = new ArrayList<>();
    ...
}

public class PersonNames extends BaseIdentityIdEntity {
    ...
    @Column(name = "LAST_NAME", nullable = false)
    @NotNull
    private String lastName = "";

    @Column(name = "FIRST_NAME", nullable = false)
    @NotNull
    private String firstName = "";

    @Column(name = "SECOND_NAME")
    private String secondName = "";
    ...
}

Есть экран Browse для вывода списка сущностей Employee, в котором используется view

<view>
    ...
    <property name="person" fetch="JOIN">
        <property name="personNamesList" view="_minimal" fetch="JOIN"/>
    </property>
    ...
</view>

Имеется, например, некий набор данных
Таблица Employee

id person_id
1 1
2 2

Таблица Person

id
1
2

Таблица **PersonNames **

id person_id last_name first_name second_name
1 1 Иванова Елена Александровна
2 1 Петрова Елена Александровна
3 2 Степанова Ирина Павловна
4 2 Максимова Ирина Павловна
5 2 Александрова Ирина Павловна

В итоге запрос выглядит типа такого: SELECT ... FROM Employee LEFT OUTER JOIN Person... LEFT OUTER JOIN PersonNames....
Такой запрос, очевидно, выведен не 2 строки, а 5. Дальше ORM творит магию, собирает сущности и мы в таблице видим две строки, двух сотрудников.

И когда экран без фильтра, то проблем нет. Сущности загрузились, я каким-то образом выбираю из списка нужное ФИО и отображаю в ячейке таблицы.

Предположим добавили фильтр, который ничего не фильтрует, но в нём установлено число отображаемых строк 2. В результате этого в конце запроса (БД Postgresql) добавиться LIMIT 2 OFFSET 0 и в итоге в таблице (в экране) вы увидим одну строку, только одного сотрудника. Тут понятно почему это происходит - из-за JOINов и LIMITа.
Вопрос в том, можно ли это как-то победить? И использовать JOINы, и видеть в таблице то количество строк, сколько выбрал (естественно что в БД есть столько сущностей).

Это первый вопрос.


Вопрос второй.

В некоторых ситуациях, как я понимаю, когда много JOINов, примерно как в моём случае, EclipseLink как-то по особенному загружает и собирает результат и у меня возникает ошибка:

Caused by: java.lang.NullPointerException: null
	at java.util.ArrayList.<init>(ArrayList.java:178) ~[na:1.8.0_232]
	at org.eclipse.persistence.mappings.ForeignReferenceMapping.prepareNestedJoinQueryClone(ForeignReferenceMapping.java:2501) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.mappings.OneToOneMapping.valueFromRowInternalWithJoin(OneToOneMapping.java:1818) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.mappings.ForeignReferenceMapping.valueFromRow(ForeignReferenceMapping.java:2200) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.mappings.ForeignReferenceMapping.buildCloneFromRow(ForeignReferenceMapping.java:350) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.mappings.ForeignReferenceMapping.buildCloneFromRow(ForeignReferenceMapping.java:373) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildAttributesIntoWorkingCopyClone(ObjectBuilder.java:2007) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneFromRow(ObjectBuilder.java:2268) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:858) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:745) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:699) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:850) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:968) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:579) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1221) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:914) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1180) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:466) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1268) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:3020) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1892) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1874) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1839) ~[org.eclipse.persistence.core-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:262) ~[org.eclipse.persistence.jpa-2.7.3-19-cuba.jar:na]
	at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:482) ~[org.eclipse.persistence.jpa-2.7.3-19-cuba.jar:na]
	... 113 common frames omitted

С самой ошибкой всё понятно. В “кишках” EclipseLink есть такой код, который выполняется (как я понял) когда много JOINов и там возникает исключение.

List nestedDataResults = dataResults;
if (nestedDataResults == null) {
    Object sourceKey = this.descriptor.getObjectBuilder().extractPrimaryKeyFromRow(row, executionSession);
    nestedDataResults = joinManager.getDataResultsByPrimaryKey().get(sourceKey); // ТУТ в HashMap нет элемента с искомым ключём, поэтому nestedDataResults = null
}
nestedDataResults = new ArrayList(nestedDataResults); // ТУТ nestedDataResults = null и возникает исключение

И ошибка возникает только когда на экране используется фильтр. Вероятно опять это из-за LIMITa.
Сталкивался ли кто-то с такой проблемой и есть ли решение (помимо отказа от JOINов)?

Добрый день,

Попробуйте добавить в JPQL запрос ключевое слово DISTINCT.

Ну, это баг в EclipseLink. Нужно понимать, что фетч-планы мы можем написать какие угодно, но не факт, что движок ORM это сможет выполнить. Поэтому лучше в этом случае изменить способ выборки например на BATCH.