2010-04-15 3 views
5

Ich versuche, ein einfaches EAV-Muster in meiner Web-App mit Java/Spring MVC und Hibernate einzurichten. Ich kann nicht die Magie hinter dem Hibernate-XML-Setup für dieses Szenario herausfinden.Implementieren EAV-Muster mit Ruhezustand für Benutzer -> Einstellungen Beziehung

Meine Datenbanktabelle "SETUP" hat drei Spalten:

  • user_id (FK)
  • setup_item
  • setup_value

Die Datenbank zusammengesetzten Schlüssel aus User_id gemacht | setup_item

Hier ist die Setup.java Klasse:

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

Mein Problem mit dem Hibernate-Setup ist, dass ich nicht herausfinden können, scheinen wie die Tatsache kartieren, dass ein Fremdschlüssel und der Schlüssel einer Karte wird der zusammengesetzte Schlüssel der Tabelle erstellt ... dies liegt an mangelnder Erfahrung mit Hibernate. Hier ist mein erster Versuch in diese an die Arbeit:

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

Einsicht darüber, wie richtig diese gemeinsame Szenario abbilden würden die meisten geschätzt werden!

+0

@Trevor Willkommen, aber wenn Sie eine nützliche Antwort sehen, UPvote, Danke! –

Antwort

2

Wie sich gezeigt, Sie haben eine inkonsistent Mapping

Sie die Setup-Klasse einen zusammengesetzten Primärschlüssel definiert (man beachte ich habe einen zusammengesetzten Primärschlüssel Klasse erstellt (SetupId - siehe unten), die Serializable implementiert, muss und gleich und Hash-Code-Methode)

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

    } 

} 

Aufgrund Ihrer Setup-Klasse eine Karte von Wert Typ hat, Sie soll seine definieren Verbundfremdschlüssel, wenn seine Beziehung (siehe Schlüsselelement definieren)

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

Und zugleich, eine zusammengesetzte Fremdschlüsselspalte als map-Taste (BENUTZER_ID, nicht wahr?), Das macht keinen Sinn. Warum ?

  • Hibernate nicht erlaubt Sie

Daneben ein (Composite) Primärschlüsselspalte aktualisieren, Hibernate nicht die automatische Generierung unterstützt von zusammengesetzten Primärschlüssel

hier Angenommen, geht Ihr SETUP Tabelle

SETUP_ITEM USER_ID 
0   1 
0   2 

Und Ihr data_table

SETUP_ITEM USER_ID 
0   1 

Was, ob Sie wegen Vortisch ein BENUTZER_ID definiert nicht versuchen, die folgenden

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

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

geschieht, den Wert 3 ist, erhalten Sie eine Einschränkungsverletzung sehen.

man sich vor Augen halten

Wenn Sie einen (Composite) Primärschlüssel haben, die nicht aktualisierbar sein kann, vermeiden, es zu benutzen, someway, eine veränderbare Eigenschaft zu ändern, die davon abhängt. Andernfalls wird Hibernate es beschweren.

Verwandte Themen