JPA Карта карт

У меня есть структура данных, которая сводится к:

class StylesheetUserPreferencesImpl {
    long id;
    String desc;
    Map<String, Map<String, String>> nodeAttributes;
}

Чтобы попытаться сделать аннотации JPA2 немного более разумными, я создал небольшой класс для представления внутреннего класса:

class LayoutAttributeImpl {
    String nodeId;
    private Map<String, String> attributes;
}

Что дает мне:

class StylesheetUserPreferencesImpl {
    long id;
    String desc;
    Map<String, LayoutAttributeImpl> nodeAttributes;
}

В конце концов, я хотел бы, чтобы структура таблицы выглядела так:

SS_USER_PREFS
    PREFS_ID
    DESC

SS_LAYOUT_ATTRS
    PREFS_ID
    NODE_ID
    NAME
    VALUE

Я не совсем уверен, как это сделать в JPA. Кажется, я хочу, чтобы LayoutAttributeImpl был встраиваемым, но, насколько я понимаю, встраиваемые объекты не могут содержать коллекции. У меня это работает прямо сейчас с LayoutAttributeImpl, действующим как полноценный @Entity, но это дает мне дополнительную таблицу, которая мне действительно не нужна.


person Eric    schedule 08.03.2011    source источник


Ответы (1)


Как насчет чего-то вроде:

class StylesheetUserPreferencesImpl {
    long id;
    String desc;
    Map<AttributeCoordinate, String> attributes;
}

class AttributeCoordinate {
    String nodeID;
    String prefID;
}

Это очень прямо сопоставляется с нужными вам таблицами — Embeddables могут быть ключами в сопоставлениях, верно? Если вы всегда одновременно ищете атрибуты как с узлом, так и с идентификатором предпочтения, вы можете скрыть эту немного странную структуру объекта внутри геттера.

Если вы хотите иметь возможность манипулировать целыми картами атрибутов отдельного узла, у вас есть проблема. Вы можете написать реализацию Map, которая подделывает его: он содержит идентификатор узла и обрабатывает поиск, рассматривая ключ как идентификатор предпочтения, а затем выполняя поиск с парой из них.

Имеет ли это хоть какой-то смысл? Я только что съел много блинов, и, возможно, я плохо соображаю.

person Tom Anderson    schedule 08.03.2011
comment
Это имеет смысл. Сейчас я занимаюсь каким-то другим рефакторингом, но я попробую это, как только смогу. Я уже скрываю карту атрибутов с помощью методов доступа, поэтому скрытие странного ключа карты должно быть возможным. Я обязательно отмечу ответ как принятый, как только проверю его. Надеюсь, блины были хороши. - person Eric; 10.03.2011
comment
Это сработало, я использовал метод @PostLoad, чтобы сбросить эту карту в Map‹String, Map‹String, String››, поскольку клиентский код должен выполнять много поиска связанных данных только по nodeId. Спасибо еще раз за помощь! - person Eric; 10.03.2011
comment
Гениальный ход с @PostLoad. - person Tom Anderson; 10.03.2011