Почему Hibernate создал таблицу объединения, которая не позволяет мне удалять содержимое таблицы

#java #hibernate

#java #hibernate

Вопрос:

У меня есть три объекта Hibernate:

  • Обложка
  • Песня

Песня представляет собой файл песни (например, файл mp3), обложка содержит обложку песни, песня может содержать несколько фрагментов обложки

В песне я определяю ссылку на обложку как:

 @OneToMany(fetch=FetchType.LAZY, cascade={CascadeType.ALL})
@JoinColumn(name = "recNo")
private List<CoverArt> coverArts;
  

В CoverArt нет ссылки, определенной на песню, у нас просто есть

 @Id
@GeneratedValue
private Integer id;
  

Приложение работает нормально, за исключением случаев, когда я хочу очистить объекты Song и CoverArt.

Это происходит не всегда, но если я сначала попытаюсь удалить из песни

 e.g 
            String hql = String.format("delete from CoverArt");
            Query query = session.createQuery(hql);
            query.executeUpdate();

            hql = String.format("delete from Song");
            query = session.createQuery(hql);
            query.executeUpdate();

            session.getTransaction().commit();
  

Я получаю исключение:

Вызвано: org.h2.jdbc.JdbcSQLException: нарушение ограничения ссылочной целостности: «FK_CBUK1UQ1D0DQAA077XH16SRX2: ВНЕШНИЙ КЛЮЧ PUBLIC.SONG_COVERART (COVERARTS_ID) ССЫЛАЕТСЯ НА PUBLIC.COVERART(ID) (13)»; Инструкция SQL:

и если я попробую другим способом

 String hql = String.format("delete from Song");
            Query query = session.createQuery(hql);
            query.executeUpdate();

            hql = String.format("delete from CoverArt");
            query = session.createQuery(hql);
            query.executeUpdate();
  

Я получаю исключение

Вызвано: org.h2.jdbc.JdbcSQLException: нарушение ограничения ссылочной целостности: «FK_4B4O39V3RSF1IWWRIX6QQQTLK: ВНЕШНИЙ КЛЮЧ PUBLIC.SONG_COVERART (SONG_RECNO) ССЫЛАЕТСЯ НА PUBLIC.SONG(RECNO) (1)»; Оператор SQL:

Таким образом, невозможно очистить таблицы, объект CoverArt существует только как часть песни, поэтому я предположил, что это будет только внешний ключ из таблицы COVER_ART в таблицу SONG, и ожидал, что смогу удалить все из CoverArt без проблем, но есть промежуточная таблица, созданная SONG_COVERART, которая имеет внешние ключи к обеим таблицам, предотвращающие удаление.

Что я делаю не так (используя Hibernate 4.3.11)

Комментарии:

1. Вероятно, потому, что в предыдущей версии вашего кода не было аннотации JoinColumn, и Hibernate, таким образом, создал таблицу объединения для этой ассоциации, которую вы заполнили, но забыли удалить.

2. @JBNizet Я думаю, у вас это есть, потому что я сам не видел ошибку, только некоторые клиенты, и я только что включил hibernate.show_sql и воссоздал базу данных, и нет таблицы SONG_COVERART, если вы хотите опубликовать ответ, я отмечу как правильный.

3. @JBNizet ах, итак, воссоздаю базу данных с конфигурацией config = getInitializedConfiguration(); config.setProperty(Environment. HBM2DDL_AUTO, «создать»); не решит проблему, потому что проблемная таблица все еще будет существовать, поскольку Hibernate больше не знает об этом, поэтому я просто вручную добавляю оператор SQL drop?

4. Я бы никогда не использовал hbm2ddl для работы с реальной производственной базой данных, содержащей данные. Это хорошо для быстрого прототипирования, но не для поддержания реальной базы данных с данными, которые должны быть должным образом перенесены. FlywayDB и Liquibase — гораздо лучшие инструменты, предназначенные для этого.

5. @JBNizet Я посмотрю на это, но это всего лишь база данных приложения, которую обычно не нужно сохранять более нескольких недель за раз, пожалуйста, подтвердите, что мне придется выполнять отдельное удаление

Ответ №1:

Вероятно, потому, что в предыдущей версии вашего кода не было аннотации JoinColumn, и Hibernate, таким образом, создал таблицу объединения для этой ассоциации, которую вы заполнили, но забыли удалить.