Использование Hibernate с картой для атрибутов таблицы - PullRequest
2 голосов
/ 30 ноября 2011

Итак, у меня есть некоторый код, который представляет метаданные песни, вместо того, чтобы иметь методы получения и установки для каждого поля, я помещаю значения в карту, каждое поле является строкой, и у меня есть отдельное перечисление для каждого поля. Это значительно упрощает код

Сейчас я хочу гибернизировать этот код, я потеряю эту простоту и должен иметь геттеры и сеттеры для каждого поля

public class Song
{

    protected final EnumMap<SongFieldKey,SongField> fields = new EnumMap<SongFieldKey,SongField>(SongFieldKey.class);


    public Song()
    {

    }


    /**
     * Return table cell datatype
     */
    public final SongField getField(SongFieldKey field)
    {
        return fields.get(field);
    }


    ................
}

public enum SongFieldKey
{
    ALBUM,
    ALBUM_ARTIST,
    ALBUM_ARTIST_SORT,
    ALBUM_SORT,
    AMAZON_ID,
    ARRANGER,
    ARTIST,
    ....
}

1 Ответ

1 голос
/ 30 ноября 2011

Прежде всего, Hibernate позволяет отображать Map s, Entity Map a и Collections простых типов данных и классов.

Вы бы сделали это так (для Map<String, String>):

<map name="songFields">
  <key column="id"/>
  <index column="name" type="string"/>
  <element column="songField" type="string"/>
</map>

С такой записью в вашем hbm.xml все значения, которые вы поместите на карту, будут сохранены во вновь созданной таблице с именем songFields.

Итак, в худшем случае ваш пример мог бы работать, если бы вы заменили enum набором статических String полей (что, я полагаю, вы не хотите делать, не так ли?

Когда вы пытаетесь заменить string типом Enum, отображение не будет работать из коробки. Что вам нужно сделать, так это как-то сопоставить ваш класс Enum с полем varchar в БД.

Это способ, которым вы можете это сделать.

Во-первых, в вашем файле *.hbm.xml определите новый тип класса org.hibernate.type.EnumType, указав SongFieldKey в качестве параметра enumClass и 12 в качестве type. (Магия 12 определяется в java.sql.Type как VARCHAR.)

 <hibernate-mapping>
    <typedef name="songFieldKey" class="org.hibernate.type.EnumType">
        <param name="enumClass">org.nowaq.hql.enums.SongFieldKey</param>
        <param name="type">12</param>
    </typedef>

    ...
 </hibernate-mapping>

Если у вас есть это, вы можете написать <map ..., заменив string на songFieldKey, например:

<map name="songFields">
  <key column="id"/>
  <index column="fieldId" type="songFieldKey"/>
  <element column="field" type="string"/>
</map>

Это должно решить вашу проблему "нет получателей и установщиков". (Я предполагал, что для простоты в теге <element> не используется тип SongField, поэтому моя карта выглядела так в коде: private EnumMap<SongFieldKey, String> fields;.)

В любом случае, убедитесь, что поняли эффективность этого решения и взгляните на эти:

Надеюсь, это поможет. Работал с Hibernate 3.4 и MySQL5 db.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...