Как правильно отобразить коллекцию перечислений в спящем режиме? - PullRequest
0 голосов
/ 10 января 2019

У меня есть объект, который ссылается на список типов enum. Список хранится в базе данных следующим образом:

userName    role
-----------------------
user0001    role1
user0001    role2
user0001    role3
user0002    role1

Соответствующий класс Java примерно такой:

@Entity
@Table(name = "UserTable")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "userId")
    private Integer id;
    @Column(name = "user_name")
    private String userName;

    @ElementCollection(targetClass = Role.class)
    @CollectionTable(name = "User_Roles")
    @Column(name = "role")
    @Enumerated(EnumType.STRING)
    private List<Role> roles;

}

Я проверил этот и этот вопрос для сопоставления. Тем не менее у меня есть две проблемы. Первая проблема заключается в том, что userName - это не PK в моем UserTable, и, насколько я знаю, hibernate присоединяется к PK.

Вторая проблема - это ошибка с текущей настройкой:

org.hibernate.LazyInitializationException: не удалось лениво инициализировать коллекция ролей: com.project.Common.User.roles, не удалось инициализировать прокси - без сеанса

Эта ошибка должна быть исправлена ​​загрузкой EAGER, но, когда я попробовал ее, я получил следующую ошибку при запуске:

java.lang.IllegalStateException: попытка зарегистрировать несколько SQL псевдонимы таблиц [role1_, role2_ и т. д.] для пространства запросов uid []

Что мне нужно изменить, чтобы это отображение работало?


Обратите внимание, что я не хотел бы вносить какие-либо изменения в базу данных, если это возможно.

Кроме того, я думаю, что на самом деле мне нужно было бы перейти с FetchType.EAGER, так как на данный момент я запрашиваю базу данных только один раз, и мне потребуется также получить роли для последующего использования. Конечно, я мог бы также изменить способ, которым мое приложение обрабатывает это, и снова запрашивать роли, когда они мне нужны явно, хотя я не уверен, что этот способ будет лучше.

1 Ответ

0 голосов
/ 10 января 2019

Хорошо, я нашел не очень хороший обходной путь. Прежде всего, я прокомментировал List<Role> roles; следующим образом:

@ElementCollection(targetClass = Role.class)
@JoinTable(name = "User_Roles", joinColumns = @JoinColumn(name = "userName"))
@Enumerated(EnumType.STRING)
@Column(name = "role")
private List<Role> roles;

Мой Role enum не имеет аннотаций.

Эта установка обычно приводит к LazyInitializationException, который я обошел, добавив System.out.println(user);, так как он получает доступ к списку roles (замена его на getRoles() привела к тому же исключению) непосредственно после выборки Пользователь.

Как вы можете догадаться, это решение на самом деле не очень хорошо / приемлемо. Пока я не найду лучшего решения (скорее всего, готового к загрузке), я буду кататься с этим.


UPDATE

Я действительно понял это. Теперь работает с eager-loading. На самом деле, настройки остались такими же, как опубликовано в ответе. IllegalStateException, о котором я упоминал в вопросе, на самом деле вызвано ошибкой HHH-12594 . Я просто удалил hibernate.default_batch_fetch_size из своей конфигурации, и тогда он работал как положено.

...