Hibernate HQL INSERT in Tabelle mit eingebetteter Klasse

Dieses Thema Hibernate - HQL INSERT in Tabelle mit eingebetteter Klasse im Forum "Data Tier" wurde erstellt von fisherman, 6. Feb. 2014.

Thema: HQL INSERT in Tabelle mit eingebetteter Klasse Hibernate: HQL INSERT in Tabelle mit eingebetteter Klasse Hallo zusammen, ich bastele gerade für Übungszwecke...

  1. 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:

    Code (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:

    Code (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:

    Code (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:

    Code (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:

    Code (Java):
    "INSERT INTO BookGenrePK (bookId, genreType) ...
    erscheint die Meldung:

    Code (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?
     
  2. Vielleicht hilft dir das Grundlagen Training weiter --> *Klick*
  3. 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:

    Code (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: 6. Feb. 2014
  4. 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:

    Code (Java):
    INSERT INTO BookGenre (bookId, genreType) ...
    Wie sieht die richtige Bezeichnung bzw. der richtige Pfad der Attribute in Klammern aus?
     
  5. 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 (Text):

    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: 7. Feb. 2014
  6. Hab's so gelöst, dass ich den composite key vereinfacht habe und den insert über das passende Objekt in einer session (saveOrUpdate()) erledige.
     
  7. Kostenloses Java-Grundlagen Training im Wert von 39 €
    Schau dir jetzt hier das Tutorial an und starte richtig durch!