Множественные ассоциации присоединения в спящем режиме

Мой вопрос связан с дизайном базы данных, а также с тем, как моделировать этот дизайн в 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, optional = true )
@NotFound( action = NotFoundAction.IGNORE )
@JoinColumns( {
  @JoinColumn( name = "BLOCK_ID", referencedColumnName = "BLOCK_ID", insertable = false, updatable = false ),
  @JoinColumn( name = "CUR_SHAPE_VERSION", referencedColumnName = "SHAPE_VERSION", insertable = false, updatable = false ) } )
public BlockShape getCurrentShape() {
    return currentShape;
}

Аннотации @NotFound потребовались, потому что Hibernate не справлялся с однозначными ассоциациями, допускающими значение NULL. Если он не находит ассоциацию, он игнорирует ее, а не выдает ошибку.

Однако меня это не очень устраивает, потому что это означает, что Hibernate на самом деле не знает о правильных отношениях между объектами. Например, если я запрашиваю currentShape не null, Hibernate не знает, как правильно выполнить этот запрос - он запрашивает block_id не равно null или cur_shape_version не равно null .

Думаю, у меня есть несколько вопросов. Во-первых, есть ли лучший способ смоделировать эту вторую ассоциацию в базе данных? Во-вторых, есть ли в Hibernate лучший способ настроить аннотации, чтобы лучше понять взаимосвязь и иметь возможность правильно запрашивать таблицу фигур?

Спасибо за любую помощь.


person Markus    schedule 07.07.2011    source источник


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

person JB Nizet    schedule 07.07.2011
comment
Спасибо JB, это решение все исправило и немного упростило ассоциации таблиц. - person Markus; 07.07.2011