среда, апреля 14, 2010

Составной первичный ключ из двух FK

Встретился несколько необычный случай отображения данных.
На картинке показаны соответствующие таблицы.





В EVENT_KIND содержится список каких-то видов событий, а в VALID_EVENT_KIND - список допустимых сочетаний "предыдущий вид события" - "следующий тип события".

Если работа с EVENT_KIND типична и ничего интересного не представляет, то вот случай с VALID_EVENT_KIND - интереснее.
Классогенератор Netbeans отказыватеся генерировать для этой таблицы соответствующий Entity, резонно, в некотором смысле, сообщая о том, что это ведь обычная таблица связи (для отношения многие-ко-многим), а поэтому и сущность соответствующая не нужна. А раз не нужна, то и делать не буду (упорный, блин).

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

Итак, раз для нас код сгенерировать отказались, остаётся написать его самому. К счастью, особо тут и писать нечего.

Вот так выглядит класс, соответствующий VALID_EVENT_KIND

@Entity
@Table(name="VALID_EVENT_KIND")
public class ValidEventKind implements Serializable {

    @EmbeddedId
    private ValidEventKindPk pk;

    public ValidEventKind() {}

    public ValidEventKind(EventKind prevEvent, EventKind nextEvent) {
        this.pk = new ValidEventKindPk(prevEvent, nextEvent);
    }
}
Ничего интересного, за исключением @EmbeddedId.
А вот и описание самого первичного, embedded-ного, ключа:

@Embeddable
public class ValidEventKindPk implements Serializable {
    @ManyToOne()
    @JoinColumn(name="prev_event", referencedColumnName="code")
    private EventKind prevEventKind;

    @ManyToOne
    @JoinColumn(name="next_event", referencedColumnName="code")
    private EventKind nextEventkind;

    public ValidEventKindPk() { }

    public ValidEventKindPk(EventKind prevEventKind, EventKind nextEventKind) {
        this.prevEventKind = prevEventKind;
        this.nextEventkind = nextEventKind;
    }
}
Разные getters и setters в обоих классах я, очевидное дело, опустил.

Вот и всё...

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