2010-02-24 16 views
25

Stosowanie adnotacji w jaki sposób mapujesz pole w obiekcie, który jest "Mapą" (HashTable) ciągu do danego obiektu? Obiekt jest opatrzony komentarzem, a jego instancje są już przechowywane w bazie danych hibernacji.Jak mapować "Mapę" w trybie hibernacji za pomocą adnotacji?

Znalazłem składnię dla definging mapę z prostego klucza i wartości jako takie:

<class name="Foo" table="foo"> 
    ... 
    <map role="ages"> 
     <key column="id"/> 
     <index column="name" type="string"/> 
     <element column="age" type="string"/> 
    </map> 
</class> 

i dziwnie z podmiotem jako klucz i prosty typu jako wartość tak:

<class name="Foo" table="foo"> 
    ... 
    <map role="ages"> 
    <key column="id"/> 
    <index-many-to-many column="person_id" 
     class="Person"/> 
    <element column="age" type="string"/> 
    </map> 
</class> 
<class name="Person" table="person"> 
    ... 
    <property name="name" column="name" 
     type="string"/> 
</class> 

Ale nie widzę, jak to zrobić dla prostego klucza do mapowania elementów, a nie widzę, jak to zrobić za pomocą adnotacji.

+1

Jest prawidłowo wyjaśnione tutaj http://stackoverflow.com/questions/3393649/storing-a-mapstring-string-using-jpa – jalogar

Odpowiedz

33

mógłby po prostu użyć adnotacji WZP@MapKey (zauważ, że adnotacji WZP różni się od Hibernate jedna, Hibernate @MapKey mapuje kolumna bazy danych przytrzymanie klawisza mapy, natomiast adnotacji w WZP mapuje właściwość może być użyty jako klucz mapy).

@javax.persistence.OneToMany(cascade = CascadeType.ALL) 
@javax.persistence.MapKey(name = "name") 
private Map<String, Person> nameToPerson = new HashMap<String, Person>(); 
+0

Dzięki temu spróbuję tego. Jakiego rodzaju schematu databse to odzwierciedla? Używam jednostki DB i chcę móc wypełnić zestaw danych przy użyciu XML. Czy to używa tabeli sprzężenia? jeśli tak, możesz określić, do czego służy tabela i jakie są kolumny tabeli łączenia? –

+2

@Omar Tworzy tabelę łączenia (domyślnie FOO_PERSON). Możesz kontrolować nazwę za pomocą '@ javax.persistence.JoinTable'. Nie jestem pewien co do kolumn. –

1

Powinieneś prawdopodobnie używać typu UserType lub UserCollectionType. Lub możesz użyć niestandardowego tupleizera.

patrz pojęcia hibernate core documentation dla koncepcji i hibernate annotations documentation dla równoważnego podejścia do adnotacji.

Daj mi znać, jeśli nie o to pytasz.

+0

Nienawidzę brzmieć jak idiota, ale patrzyłem na te same dwie strony i wyłączam cały dzień, a ja nie wydaje się, że to rozumiem. Patrzyłem na ten styl: Co wydaje mi się potrzebne, po prostu nie rozumiem, jak to zrobić jako adnotację. Nie wiem też, jak bym to zrobił, gdyby element nie był łańcuchem. Czy mam zły koniec kija. –

+0

Tak, myślę, że naprawdę chcesz UserType, ponieważ wszystkie inne elementy omówione tutaj (jak sądzę) tworzą kolejną tabelę do przechowywania mapy. Zobacz interfejs UserType, a zobaczysz, że istnieje tylko kilka metod do wdrożenia. Zasadniczo mówisz hibernację, biorąc pod uwagę ResultSet, jak umieścić go w typie Java i na odwrót. –

8
@CollectionOfElements(fetch = FetchType.LAZY) 
@JoinTable(name = "JOINTABLE_NAME", 
    joinColumns = @JoinColumn(name = "id")) 
@MapKey(columns = @Column(name = "name")) 
@Column(name = "age") 
private Map<String, String> ages = new HashMap<String, String>(); 
+0

Tego właśnie szukam, ale jak by to zrobić, gdyby klucz był ciągiem jak w przykładzie, a wartość była innym obiektem? –

+0

To wygląda podobnie do adnotacji do mapowania Enum. –

+0

@Omar: Powinno być tak proste jak zamiana "String" na wybrany typ obiektu. Być może trzeba będzie usunąć @Column (name = "age") i dodać coś takiego jak inverseJoinColumns = @ JoinColumn (name = "fk_ik") do adnotacji @ JoinTable. Nie jestem tego pewien. – whiskeysierra

2

Wiem, że to pytanie jest bardzo stare, ale może to może pomóc komuś.

Inne posibility jest coś takiego:

@Entity 
@Table(name = "PREFERENCE", uniqueConstraints = { @UniqueConstraint(columnNames = { "ID_DOMAIN", "ID_USER", "KEY" })}) 
public class Preferences { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "ID", unique = true, nullable = false) 
    private Long id; 

    @Column(name = "ID_DOMAIN", unique = false, nullable = false") 
    private Long domainId; 

    @Column (name = "PREFERENCE_KEY") 
    @Enumerated(EnumType.STRING) 
    private PreferenceKey key; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "ID_USER", referencedColumnName = "ID") 
    private User user; 
} 

and 

@Entity 
@Table(name = "USER", uniqueConstraints = { @UniqueConstraint(columnNames = { "ID_DOMAIN", "LOGIN" })}) 
public class User { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "ID", unique = true, nullable = false) 
    private Long id; 

    @Column(name = "ID_DOMAIN", unique = false, nullable = false") 
    private Long domainId; 

    // more fields 

    @ElementCollection(fetch = FetchType.LAZY) 
    @JoinColumns({@JoinColumn(name = "ID_USER", referencedColumnName = "ID"), @JoinColumn(name = "ID_DOMAIN", referencedColumnName = "ID_DOMAIN")}) 
    @OneToMany(targetEntity = Preferences.class, fetch = FetchType.LAZY) 
    @MapKey(name = "key") 
    private Map<PreferenceKey, Preferences> preferencesMap; 
} 

która produkuje tylko dwa stoły i preferencji użytkowników, należy pamiętać, że PreferenceKey jest unikalny dla użytkownika w domenie

Powiązane problemy