Несколько объединений объединений в спящем режиме

Мой вопрос связан с дизайном базы данных, а также с тем, как смоделировать этот дизайн в 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 не рекомендует использовать составные ключи (и проблема, с которой вы столкнулись, является лишь одной из них).

Другие вопросы по тегам