Несколько объединений объединений в спящем режиме
Мой вопрос связан с дизайном базы данных, а также с тем, как смоделировать этот дизайн в Hibernate. У меня есть две таблицы со следующими первичными ключами:
BLOCK (BLOCK_ID)
BLOCK_SHP (BLOCK_ID, SHAPE_VERSION)
BLOCK to BLOCK_SHP - это отношение "один ко многим", поскольку у одного блока может быть много разных версионных форм, связанных с ним. Все идет нормально.
Вторая ассоциация заключается в том, что я также хочу иметь возможность получить текущую форму для блока. Для этого я добавил еще один атрибут в таблицу BLOCK:
CUR_SHAPE_VERSION
BLOCK_ID и CUR_SHAPE_VERSION теперь формируют внешний ключ к таблице BLOCK_SHP для BLOCK_ID, SHAPE_VERSION. Каждый блок может иметь 0 или 1 текущих фигур.
В Hibernate я установил эту вторую связь следующим образом:
@OneToOne (cascade = CascadeType.ALL, необязательно = true) @NotFound( action = NotFoundAction.IGNORE) @JoinColumns( { @JoinColumn( name = "BLOCK_ID", referencedColumnName = "BLOCK_ID", вставляемый = ложный, обновляемый = ложный), @JoinColumn( name = "CUR_SHAPE_VERSION", referencedColumnName = "SHAPE_VERSION", вставляемый = false, обновляемый = false) }) public BlockShape getCurrentShape() { вернуть currentShape; }
Аннотация @NotFound потребовалась, потому что Hibernate испытывал трудности при работе с взаимно однозначными ассоциациями. Если он не находит ассоциацию, он игнорирует ее, а не выдает ошибку.
Это не очень приятно для меня, потому что это означает, что Hibernate действительно не знает о правильных отношениях между сущностями. Например, если я запрашиваю currentShape, не равен NULL, Hibernate не знает, как правильно выполнить этот запрос - он запрашивает block_id не NULL или cur_shape_version не NULL.
Так что, думаю, у меня есть несколько вопросов. Во-первых, есть ли лучший способ для моделирования этой второй ассоциации в базе данных? Во-вторых, есть ли лучший способ в Hibernate настроить аннотации для него, чтобы лучше понять взаимосвязь и иметь возможность правильно запрашивать таблицу форм?
Спасибо за любую помощь.
1 ответ
Самый простой способ - использовать суррогатный первичный ключ для объекта Shape. Таблицы будут выглядеть так:
BLOCK (BLOCK_ID primary key, CURRENT_SHAPE_ID foreign key references SHAPE.SHAPE_ID)
SHAPE (SHAPE_ID primary key, SHAPE_VERSION, BLOCK_ID foreign key references BLOCK.BLOCK_ID)
По понятным причинам Hibernate не рекомендует использовать составные ключи (и проблема, с которой вы столкнулись, является лишь одной из них).