Реализация шаблона EAV с В спящем режиме для Пользователя-> отношения Настроек

Я пытаюсь установить простой шаблон EAV в своем использовании веб-приложения Java/Spring MVC и Быть в спящем режиме. Я, может казаться, не выясняю волшебство позади того, чтобы быть в спящем режиме установки XML для этого сценария.

Моя таблица базы данных "УСТАНОВКА" имеет три столбца:

  • user_id (FK)
  • setup_item
  • setup_value

Составной ключ базы данных составлен из user_id | setup_item

Вот класс Setup.java:

public class Setup implements CommonFormElements, Serializable {
  private Map data = new HashMap();
  private String saveAction;
  private Integer speciesNamingList;
  private User user;

  Logger log = LoggerFactory.getLogger(Setup.class);

  public String getSaveAction() {
    return saveAction;
  }

  public void setSaveAction(String action) {
    this.saveAction = action;
  }

  public User getUser() {
    return user;
  }

  public void setUser(User user) {
    this.user = user;
  }

  public Integer getSpeciesNamingList() {
    return speciesNamingList;
  }

  public void setSpeciesNamingList(Integer speciesNamingList) {
    this.speciesNamingList = speciesNamingList;
  }

  public Map getData() {
    return data;
  }

  public void setData(Map data) {
    this.data = data;
  }
}

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

<composite-id>
  <key-many-to-one foreign-key="id" name="user" column="user_id" class="Business.User">
    <meta attribute="use-in-equals">true</meta>
  </key-many-to-one>
</composite-id>

<map lazy="false" name="data" table="setup">
  <key column="user_id" property-ref="user"/>
  <composite-map-key class="Command.Setup">
    <key-property name="data" column="setup_item" type="string"/>
  </composite-map-key>

  <element column="setup_value" not-null="true" type="string"/>
</map>

Любое понимание, как правильно отобразить этот общий сценарий, больше всего ценилось бы!

6
задан Trevor 15 April 2010 в 14:13
поделиться

1 ответ

Как вы сами показали, у вас есть несогласованное сопоставление

Вы сказали, что класс Setup определяет составной первичный ключ (обратите внимание, что у меня создал составной класс первичного ключа (SetupId - см. ниже)который должен реализовывать метод Serializable and equals и hashcode)

package ar.domain;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

public class Setup implements Serializable {

    private SetupId setupId;

    private User user;
    private Map data= new HashMap();

    public SetupId getSetupId() {
        return setupId;
    }

    public void setSetupId(SetupId setupId) {
        this.setupId = setupId;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Map getData() {
        return data;
    }

    public void setData(Map data) {
        this.data = data;
    }


    public static class SetupId implements Serializable {

        private Integer userId;
        private String setupItem;

        public String getSetupItem() {
            return setupItem;
        }

        public void setSetupItem(String setupItem) {
            this.setupItem = setupItem;
        }

        public Integer getUserId() {
            return userId;
        }

        public void setUserId(Integer userId) {
            this.userId = userId;
        }

        @Override
        public boolean equals(Object o) {
            if (o == null)
                return false;

            if (!(o instanceof SetupId))
                return false;

            final SetupId other = (SetupId) o;
            if (!(getUserId().equals(other.getUserId())))
                return false;
            if (!(getSetupItem().equals(other.getSetupItem())))
                return false;

            return true;
        }

        @Override
        public int hashCode() {
            int hash = 7;
            hash = 11 * hash + (getUserId() != null ? getUserId().hashCode() : 0);
            hash = 11 * hash + (getSetupItem() != null ? getSetupItem().hashCode() : 0);
            return hash;
        }

    }

}

Поскольку ваш класс Setup имеет Map of value Type, вы должны определить его составной внешний ключ при определении его отношения (см. ключевой элемент)

<class name="ar.domain.Setup">
    <composite-id name="setupId" class="ar.domain.Setup$SetupId">
        <key-property name="setupItem" type="string" column="SETUP_ITEM"/>
        <key-property name="userId" type="integer" column="USER_ID"/>
    </composite-id>
    <many-to-one name="user" class="ar.domain.User" column="USER_ID" insert="false" update="false"/>
    <map name="data" table="DATA_TABLE">
        <key>
            <column name="SETUP_ITEM"/>
            <column name="USER_ID"/>
        </key>
        <map-key column="USER_ID"/>
        <element column="SETUP_VALUE" not-null="true" type="string"/>
    </map>
</class>

И в то же время использовать столбец составного внешнего ключа в качестве ключа сопоставления (USER_ID, верно?), Что не имеет смысла. Почему?

  • Hibernate не позволяет обновлять (составной) столбец первичного ключа

Кроме того, Hibernate не поддерживает автоматическое создание составного первичного ключа

Предположим вот ваша таблица SETUP

SETUP_ITEM USER_ID
0          1
0          2

и ваша DATA_TABLE

SETUP_ITEM USER_ID
0          1

Что произойдет, если вы попробуете следующую

Integer userId = 3;
String setupValue = "someValue";

setup.getData().put(userId, setupValue);

Поскольку таблица SETUP не определяет USER_ID, значение которого равно 3, вы увидите нарушение ограничения .

Помните об этом

Если у вас есть (составной) первичный ключ, который не может быть обновлен, так или иначе избегайте его использования для изменения изменяемого свойства, которое от него зависит . В противном случае Hibernate будет жаловаться на это.

2
ответ дан 17 December 2019 в 20:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: