Повторяющиеся элементы в атрибуте списка объекта гибернации - PullRequest
0 голосов
/ 24 ноября 2018

Проблема, которую я пытаюсь решить, состоит в том, чтобы избежать дублирования элементов в атрибуте списка в спящем режиме.Рассмотрим домен ниже.

public class Account
    {
        @OneToMany(fetch = FetchType.LAZY)
        @JoinTable(name = "FI_COMPANY_ACCOUNT", joinColumns = @JoinColumn(name = "ACCOUNT_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "COMPANY_ID", referencedColumnName = "ID"))
        private List<Company> companies;

        @OneToMany(fetch = FetchType.LAZY, mappedBy = "account", cascade = CascadeType.ALL, orphanRemoval = true)
        private List<AccountDesc> accountDescList;
    }

public class Company {}

public class AccountDesc
{
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "PARENT_ID", referencedColumnName = "ID")
    private Account account;
}

Я использую Criteria API для получения учетной записи.В запросе я выполняю выборку, используя левое соединение для компаний и внутреннее соединение для атрибута accountDescList.Это помогает мне получить оба атрибута при первом выборе и избежать дальнейших выборов.

Root<Account> root = criteriaQuery.from(Account.class);
root.fetch("companies", JoinType.LEFT);
root.fetch("accountDescList");

Я знаю, что корневая сущность (здесь Учетная запись) может быть повторена в результатах.Я могу решить эту проблему, используя несколько способов, например, http://in.relation.to/2016/08/04/introducing-distinct-pass-through-query-hint/ https://howtoprogramwithjava.com/how-to-fix-duplicate-data-from-hibernate-queries/

Но проблема, с которой я сталкиваюсь, заключается в том, что компании-атрибуты внутри Учетной записи также имеют дублирующиеся объекты.Это происходит, если у нас есть несколько записей для accountDescList.

Чтобы решить проблему дубликатов в компаниях-атрибутах, я считаю, что единственным решением является использование Set.Не могли бы вы уточнить следующие вопросы.

  1. Есть ли другой способ, кроме использования Set (для атрибутных компаний), для решения этой проблемы.
  2. Даже если я использую, могу ли ядайте hibernate команду использовать OrderedSetType (который использует LinkedHashSet).Так что я могу сохранить порядок элементов, как он вернулся из базы данных.К сожалению, у меня нет атрибута для использования в OrderBy.Мне нужен любой порядок по умолчанию, возвращаемый базой данных.

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Но проблема, с которой я сталкиваюсь, заключается в том, что компании-атрибуты внутри Учетной записи также имеют дублирующиеся сущности.

Этого не должно быть, если у вас нет дублирующихся Company сущностей, назначенных одной учетной записи..

Как объяснено в этой статье , использование DISTINCT в запросе API Criteria удалит корневые дубликаты.Однако в вашем случае не стоит использовать JOIN FETCH для обоих отношений @OneToMany, так как это приведет к декартовому произведению.

Вы должны получать не более одной коллекции за раз, и, возможно, использовать @Subselect выборкудля второй коллекции.

0 голосов
/ 24 ноября 2018

Я думаю, что намного лучше использовать Set, потому что набор не позволяет дублировать элементы, также вы можете перезаписать метод equals Company и указать, какие поля будут проверяться, когда два элемента равны.Другой способ заключается в методе setCompanies (список компаний), который вы можете сделать чем-то логичным до this.companies = companies.stream (). Different (). Collect (Collectors.toList ());или this.companies = new ArrayList <> (новый HashSet (компании));

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...