2010-04-15 8 views
5

Próbuję skonfigurować prosty wzór EAV w mojej aplikacji internetowej przy użyciu Java/Spring MVC i Hibernate. Nie potrafię zrozumieć magii konfiguracji hibernacji XML dla tego scenariusza.Implementacja wzoru EAV z Hibernate dla użytkownika -> Ustawienia relacji

Moja baza stół "SETUP" ma trzy kolumny:

  • user_id (FK)
  • setup_item
  • setup_value

Klucz kompozytowa baza danych składa się z user_id | setup_item

Oto klasa 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; 
    } 
}

Mój problem z konfiguracji hibernacji, jest to, że nie może wydawać się, aby dowiedzieć się jak mapować uwagę na fakt, że klucz obcy i klucz mapy utworzy złożony klucz tabeli ... wynika to z braku doświadczenia przy korzystaniu z Hibernate. Oto moja pierwsza próba w coraz to do pracy:

<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> 

Każdy wgląd w jaki sposób poprawnie map to wspólny scenariusz byłby najbardziej mile widziane!

+0

@Trevor Witaj, ale jeśli zobaczysz użyteczną odpowiedź, UPvote, Dzięki! –

Odpowiedz

2

Jak widać sam, masz niespójne mapowanie

Mówiłeś klasa konfiguracja definiuje kompozytowy klucz podstawowy (Zawiadomienie Stworzyłem kompozytowego klasy klucza podstawowego (SetupId - patrz poniżej), które muszą implementuje Serializable i równy i metody 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; 
     } 

    } 

} 

powodu swojej klasie Instalator mapa Typ wartości, należy określić jego kompozytowa klucz obcy przy określaniu jego związek (patrz kluczowy element)

<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> 

Jednocześnie należy użyć złożonej kolumny klucza obcego jako klucza mapy (USER_ID, w prawo?), Co nie ma sensu. Czemu ?

  • Hibernate nie pozwala aktualizowania (kompozytowe) podstawowy kolumna klucz

Poza tym, Hibernate nie umożliwia automatyczne generowanie kompozytowych klucz podstawowy

Załóżmy tu idzie swoje Tabela konfiguracji

SETUP_ITEM USER_ID 
0   1 
0   2 

A twój DATA_TABLE

SETUP_ITEM USER_ID 
0   1 

Co się dzieje, czy spróbować następujących jednym

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

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

Ze względu Ustawienia tabeli nie definiuje USER_ID którego wartość wynosi 3, widać naruszenie wiązania.

nich pamiętać

Kiedy masz (kompozytowe) klucza podstawowego, którego nie można uaktualniać, unikać go używać, jakoś, aby zmienić właściwość zmienny która zależy od niego. W przeciwnym razie Hibernate będzie na nie skarżyć.

Powiązane problemy