Как присоединиться к двум объектам, используя другой общий объект в спецификации JPA?

У меня есть простая модель данных с 3 элементами: Принципал (пользователь), а затем его настройки и данные профиля. UserSetting и UserProfile имеют ссылки на участника, но объект Principal не имеет ссылки ни на один из них (однонаправленный).

UserProfile ----> Principal <---- UserSettings

Вот объекты (показаны только поля, относящиеся к вопросу):

@Entity
public class Principal {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id;

    private boolean enabled; 
}

@Entity
public class UserProfile {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id;

    @OneToOne(fetch = FetchType.LAZY) 
    private Principal principal;
}

@Entity
public class UserSettings{
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id;

    @OneToOne(fetch = FetchType.LAZY) 
    private Principal principal;

    private boolean isHidden;
}

Вот рабочий запрос JPA, который объединяет таблицы и извлекает все правильные данные:

@Query( "SELECT DISTINCT(userProfile) " +
    "FROM UserProfile userProfile " +
    "LEFT JOIN FETCH userProfile.principal AS principal " +
    "WHERE principal.enabled = :enabled " +
    "AND principal.id IN ( " +
        "SELECT userSettings.principal.id " +
        "FROM UserSettings userSettings " +
        "WHERE userSettings.isHidden = :hidden)")

Есть ли способ создать спецификации JPA, которые будут делать следующее (имейте в виду, что у принципала нет ссылок на UserSettings или UserProfile):

а) Отфильтруйте профили пользователей, чьи принципы не включены

WHERE principal.enabled = :enabled

б) Отфильтровать профили пользователей для тех, кто решил скрыться в настройках пользователя.

AND principal.id IN (
    SELECT userSettings.principal.id
    FROM UserSettings userSettings
    WHERE userSettings.isHidden = :hidden
)

person SergeyB    schedule 12.12.2013    source источник


Ответы (1)


На вашем месте я бы создал двунаправленную @OneToOne связь между UserProfile и UserSettings

person Flying Dumpling    schedule 12.12.2013
comment
Сброс. Забавно, что вы это говорите, но на самом деле я нахожусь в процессе отказа от двунаправленных отношений, потому что fetch = FetchType.LAZY не работает с двунаправленными OneToOne. Потратил целый день, пытаясь понять, как заставить его не получать OneToOne, пробовал JoinColum, JoinTable, mappedBy, что угодно, ничего не получалось, кроме однонаправленных отношений. В настоящее время я пытаюсь найти решение для моего вопроса, это определенно выполнимо, я просто не очень хорошо знаком с запросами CriteriaBuilder/Specification, поэтому это оказывается немного сложным. - person SergeyB; 13.12.2013
comment
Хм, вы должны работать вне сервера приложений J2EE. Если это так, вам нужно включить плетение в вашем провайдере JPA. В J2EE AS ​​переплетение включено по умолчанию. - person Flying Dumpling; 13.12.2013
comment
взгляните на этот пост, он описывает ту же проблему, с которой я сталкиваюсь: stackoverflow.com/questions/7510131/ - person SergeyB; 03.01.2014
comment
Эти два ответа очень хороши. Просто убедитесь, что у вас включено переплетение во время выполнения, и все готово. - person Flying Dumpling; 03.01.2014