4 Stimmen

Wie Persistenz einer Map<Entity, Integer> mit JPA implementieren?

Ich arbeite gerade daran, einige Code zu migrieren, der zwei Entitäten (Fortschritt und Leistungsbewertung) enthält, die durch eine viele-zu-viele Beziehung verbunden sind. Jede Leistungsbewertung hat mehrere Fortschritte und jeder Fortschrittstyp kann mehreren Leistungsbewertungen zugewiesen werden. Darüber hinaus hat jede Leistungsbewertung->Fortschritt eine zusätzliche "Menge", die sich auf den Fortschritt bezieht.

Aktuell enthält das PerformanceRating-Objekt eine Map, die die "Menge" des Fortschritts für jeden dem PerformanceRating-Objekt zugewiesenen Fortschrittstyp darstellt.

Es ist wie folgt kodiert:

@Entity
class PerformanceRating{
....
....
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "performance_rating_progress_reward", joinColumns = { @JoinColumn(name = "id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "amount", nullable = false, updatable = false) })
public Map getRewardAmountByProgressMap() {
    return this.rewardAmountByProgressMap;
}

Wenn ich jedoch JBoss starte (mit Hibernate 3.6/JTA/JPA), erhalte ich den folgenden Fehler:

Verwendung von @OneToMany oder @ManyToMany, die auf eine nicht zugeordnete Klasse abzielen: fwl.domain.model.PerformanceRating.rewardAmountByProgressMap[java.lang.Integer]

Ich habe einen ähnlichen Thread gefunden (Persist a Map with JPA), aber dieser scheint sich mit Nicht-Entitäts-Typen zu befassen. In einem Fall wie meinem, in dem ich eine Zuordnung von Entität/Werttyp suche, was ist die richtige Syntax?

Gibt es einen Weg, dies in Hibernate/JPA2 zu tun?

Danke,

Eric

2voto

Kohányi Róbert Punkte 9261

Der Fehler, den Sie erhalten:

Verwendung von @OneToMany oder @ManyToMany, das auf eine nicht zugeordnete Klasse abzielt: fwl.domain.model.PerformanceRating.rewardAmountByProgressMap[java.lang.Integer]

bezieht sich darauf, dass Sie mit Annotationen wie @OneToMany und @ManyToMany sagen, dass die deklarierende Klasse (PerformanceRating) in einer Many-to-Many-Beziehung mit dem Wert Ihrer Karte, Integer, steht, was dumm ist.

Der Wert Ihrer Karte sollte eine Entität sein, ihr Schlüssel sollte die ID sein, mit der Sie eine dieser Entitäten identifizieren können, die Ihre Karte enthält (eigentlich muss der Schlüssel nur eindeutig sein, denke ich, es muss keine tatsächliche ID sein).


Ich weiß wirklich nicht, wie Ihre Tabelle aussieht, aber wenn Ihre PerformanceRating (nennen wir sie für die Einfachheit Rating) so aussieht:

rating
============
id               int(11) PK

und Ihre Fortschritt-Tabelle so aussieht:

progress
============
id               int(11) PK
amount           int(11)

mit einer Tabelle, die diese wie folgt verbindet:

progress_has_rating
============
progress_id      int(11) PK
rating_id        int(11) PK

dann können Sie diese folgendermaßen zuordnen:

@Entity @Table class Rating {
  @Id long id;
  @ManyToMany(targetEntity = Progress.class,
              cascade = CascadeType.ALL,
              fetch = FetchType.EAGER)
  @JoinTable(name = "progress_has_rating",
             joinColumns = {@JoinColumn(name = "rating_id", 
                                        referencedColumnName = "id")},
             inverseJoinColumns = {@JoinColumn(name = "progress_id",
                                               referencedColumnName = "id")})
  Set progresses;
}

@Entity class Progress {
  @Id long id;
  @Basic long amount;
}

(Es ist durchaus möglich, dass ich die Spaltennamen in den @JoinColumn-Annotationen vertauscht habe, die tatsächlich funktionieren würden; ich verwechsle sie immer.)

(Bearbeitung: Ja, ich habe sie vertauscht - behoben.)


Wenn Ihr amount-Eigenschaft in Ihrer Verbindungstabelle enthalten ist, müssen Sie auch eine Entitätsklasse dafür erstellen. Ich glaube, daran ist keine Entkommen möglich.

Wenn Sie wirklich Karten verwenden möchten, kann Hibernate das verwalten. Sehen Sie sich den Abschnitt Collection-Mapping (besonders Abschnitt 7.2.2.2) an, wie man Karten zuordnet. Trotzdem müssten die Werte in Ihrer Karte Entitäten irgendeiner Art sein.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X