Hibernate HQL INSERT in Tabelle mit eingebetteter Klasse

F

fisherman

Gast
Hibernate: HQL INSERT in Tabelle mit eingebetteter Klasse

Hallo zusammen,

ich bastele gerade für Übungszwecke an einem Buchladen unter Zuhilfenahme von Hibernate/JPA und JSF.
Meine aktuelle Aufgabe ist es, aus den Tabellen Book und GenreType Daten zu holen und in der Tabelle BookGenre den Büchern Genres zuzuordnen. Nun ist mir unklar, wie das HQL-Statement dazu aussehen muss.

Dazu habe ich für die Tabelle BookGenre zwei Klassen erstellt:

Java:
@Embeddable
public class BookGenrePK implements Serializable {

@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id")
	private Long id;
	@Column(name = "genre_type", nullable = false, length = 50)
	private String genreType;
	@Column(name = "book_id", nullable = false)
	private Long bookId;

	// getter und setter, equals(), hashCode()
}

Die Klasse BookGenrePK bildet einen kombinierten Primärschlüssel ab und ist in die Klasse BookGenre eingebettet:

Java:
@Entity
@Table(name = "BOOK_GENRE")
public class BookGenre implements Serializable {

	@EmbeddedId
	private BookGenrePK bookGenrePk;

	// getter und setter, equals(), hashCode()
}

Mit folgenden HQL-Statements habe ich es versucht:

Java:
"INSERT INTO BookGenre (bookId, genreType) 
SELECT b.id, gt.name from Book b, GenreType gt 
WHERE b.id = " + bookId + " and gt.name = '" + genreType + "'"

Die Fehlermeldung dazu:

Java:
java.lang.IllegalArgumentException: org.hibernate.QueryException: 
could not resolve property: bookId of: BookGenre

Das erscheint mir noch logisch.
Verwende ich im Statement stattdessen BookGenrePK:

Java:
"INSERT INTO BookGenrePK (bookId, genreType) ...

erscheint die Meldung:

Java:
java.lang.IllegalArgumentException:
org.hibernate.hql.internal.ast.QuerySyntaxException: 
BookGenrePK is not mapped

Allerdings ist die Klasse durchaus gemappt, sowohl in der hibernate.cfg.xml als auch in der persistence.xml.

Jemand eine Idee, wie das HQL-Statement aussehen müsste?
 

KSG9|sebastian

Top Contributor
Was willst du denn machen?

Embedded bedeutet das die Attribute in die eigentliche Klasse (Tabelle) wandern. Abfragen kannst du über den Propertypath, in deinem Fall, z.B:

Java:
from BookGenre b where b.bookGenrePk = ?
// query.setParameter(1, bookGenrePkInstance)

oder

from BookGenre b where b.bookgenrePk.id = 12

Deine Klasse BookGenrePk ist kein Entity sondern ein Embeddable. Daher auch die Exception wg unmapped Class.
 
Zuletzt bearbeitet:
F

fisherman

Gast
Ich möchte Folgendes machen:

In die Tabelle BookGenre bestimmte Daten aus den Tabellen Book und GenreType füllen, nämlich

Book.id --> BookGenre.bookId
GenreType.name --> BookGenre.genreType

d.h. der SELECT-Teil des Statements kommt aus den Tabellen Book und Genre. Werte für id und name übergibt das Programm zur Laufzeit.

Die Frage stellt sich wohl beim INSERT-Teil des Statements:

Java:
INSERT INTO BookGenre (bookId, genreType) ...

Wie sieht die richtige Bezeichnung bzw. der richtige Pfad der Attribute in Klammern aus?
 

KSG9|sebastian

Top Contributor
Dafür ist Hibernate absolut nicht gedacht. Du versuchst ne Datenmigration zu machen.

Warum willst du dir dafür Hibernate an's Bein binden? Migrier die Daten von den 2 Tabellen in eine Tabelle via SQL. Anschließend kannst du mit Hibernate sauber auf der Tabelle arbeiten.

Evtl. könntest du folgendes tun:

Erstell 3 Entitys:

A - CompositeEntity
B - Teil 1 (Book)
C - Teil 2 (GenreType)

Und einen CompositeKey

CompositeKey(bookId, genreType)

und dann

Code:
INSERT INTO
 CompositEntity(compositPk, att1, att2) 
SELECT 
 new CompositeKey(b.bookId, c.genreType) from B b, C c";

Dafür musst du deinen CompositePk mit einem passenden Konstruktor (bookId, genreType) ausstatten. Ich weiß allerdings nicht ob Projektionen in Verbindung mit Insert/Select funktioniert.
 
Zuletzt bearbeitet:
F

fisherman

Gast
Hab's so gelöst, dass ich den composite key vereinfacht habe und den insert über das passende Objekt in einer session (saveOrUpdate()) erledige.
 

Ähnliche Java Themen

Neue Themen


Oben