Как таблицы ассоциации / внешние ключи лучше всего обрабатываются с помощью Hibernate? - PullRequest
2 голосов
/ 18 января 2012

Я использовал schemaExport для создания таких таблиц, как эта

  Configuration config = new Configuration();
  config.addAnnotatedClass(Categories.class);
  config.addAnnotatedClass(Article.class);
  config.configure();
      new SchemaExport(config).create(true, true);

Важными компонентами Categories.java и Article.java являются:

Article.java

    @Id
@GeneratedValue
public Long getId() {
    return id;
}

    @OneToMany( cascade = CascadeType.ALL )
public Set<Categories> getCategories() {
    return categories;
}

Categories.java

    @Id
@GeneratedValue
public Long getId() {
    return id;
}

    @ManyToOne(cascade = CascadeType.ALL)
public Article getArticleCategories() {
    return articleCategories;
}

При запуске экспорта схемы создается три таблицы: Article, Categories и article_categories. article_categories - это таблица ассоциации с двумя первичными ключами, соответствующими ключам из Article и Categories. Только статья и категории были добавлены в SessionFactory в моем ApplicationContext.xml, потому что у меня, очевидно, нет третьей таблицы как класса с момента ее создания. Я написал этот HQL:

"from Article a, article_categories ac, Categories c where ac.Article_id = a.id and ac.categories_id = c.id and c.category = 'p'"

Hibernate не может запустить его, потому что article_categories не отображается. Я должен нанести на карту это? Является ли использование нативного SQL вместо HQL возможной альтернативой, или мне следует избегать таблиц ассоциаций вместе? Каково решение этой проблемы?

Ответы [ 2 ]

2 голосов
/ 18 января 2012

HQL не работает с таблицами. Работает с юридическими лицами и их объединениями. Создайте объединения между сущностями в запросе HQL, и Hibernate сгенерирует для вас соответствующий SQL, используя таблицы соединений.

Пример:

select a from Article a 
inner join a.categories c
where c.category = :categoryName

Прочитайте (как минимум) раздел HQL справочного руководства .

Примечание: название объекта должно быть в единственном числе: категория, а не категории. Таким образом, статья имеет Set<Category> с именем categories. Намного легче читать и понимать таким образом. И поле категории category должно называться name: это название категории, а не ее категория.

1 голос
/ 18 января 2012

Не слишком уверен, если у вас есть ошибка в исходной базе данных или в экспорте. Мы используем тот же подход, но потом реорганизуем таблицы. (Я постараюсь найти сценарий, который мы используем, если вам это нужно, и вернусь к этому завтра)

В любом случае: вам не нужен класс сущностей для вашего отношения m: n, если нет никаких дополнительных полей, кроме внешних ключей:

В категории:

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "article_categories",
        joinColumns = { @JoinColumn(name = "article_id", nullable = false, updatable = false) },
        inverseJoinColumns = { @JoinColumn(name = "category_id", nullable = false, updatable = false) })
private Set<Article> articles;

В статье:

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "article_categories",
            joinColumns = { @JoinColumn(name = "category_id", nullable = false, updatable = false) },
            inverseJoinColumns = { @JoinColumn(name = "article_id", nullable = false, updatable = false) })
private Set<Category> categories;

Это создаст таблицу m: n.

Когда мы запускаем экспортер hibernate, мы на самом деле получаем класс отображения и класс ключей, которые вам понадобятся, если вам нужны дополнительные столбцы в таблице m: n. Но, как я уже сказал, завтра мне придется откопать фрагмент.

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