Announcement

Collapse
No announcement yet.

Datensätze mittels Hibernate oder HQL löschen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Datensätze mittels Hibernate oder HQL löschen

    Hallo, ich stehe mal wieder vor einem kleinen Problemchen. Beim Löschen der Daten wird aus der GUI eine Methode aufgerufen:

    public void deleteData(Object object) {
    Session session = HibernateUtil.getSessionFactory().openSession();
    Transaction tx = session.beginTransaction();
    Customer customer = (Customer) object;
    String hql = "delete from Customer where strLastname = '" + customer.getStrLastname() + "'";
    Query query = session.createQuery(hql);
    System.out.println(hql);
    tx.commit();
    session.close();
    }

    Wenn ich jetzt den String mal so auf der Konsole ausgebe, dann heisst das bspw.

    delete from Customer where strLastname = 'Maier', also so weit alles i.o.

    wenn ich jetzt diesen string per Copy&Paste in der h2 database-console eingebe, dann funktioniert er auch.

    allerdings, wenn ich ihn in der query ausführe, dann funktioniert es nicht. keine fehlermeldung, nichts, er macht es einfach nur nicht, fertig.
    hab ich da einen syntaxfehler (ich wüsste nicht wo?!?) oder sonst irgendwie einen denkfehler.

    dann gibt es ja noch die möglichkeit mit session.delete(customer).

    da habe ich dann allerdings eine fehlermeldung ...

    8750 [AWT-EventQueue-0] INFO org.hibernate.event.def.DefaultDeleteEventListener - handling transient entity in delete processing

    ... mit der ich als anfänger wenig anfangen kann, die ich auch per googlen nicht gefunden habe (zumindest nicht dass, was mir meinen fehler erklärt)

    liegt es vielleicht daran, dass die ID (also mein hibernate-Primärschlüssel, in den Customer-Objekten so nicht drinsteht, weil ich das irgendwie vergessen hatte), daran arbeite ich gerade, aber irgendwie bezweifle ich, dass das die lösung für mein problem ist ...

  • #2
    Ich kenn Hibernate nicht, aber irgendwie sieht es für mich so aus, als ob Du zwar das Queryobject erzeugst den eigentlichen DELETE abe rnie ausführst.

    Des weiteren solltest Du dich mit dem Thema PreparedStatements befassen und deine SQLs nicht per Stringconcarnierung zusammenbasteln.

    Dim
    Zitat Tom Kyte:
    I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

    Comment


    • #3
      Der Hibernatefehler rührt daher, dass du versuchst ein Objekt mit Hibernate zu löschen, welches nicht persitiert ist. Hibernate kennt den customer nicht. Eine ID ist bei der Nutzung von Hibernate in den Entity-Klassen zwingend erforderlich.

      Deine Query wird nicht ausgeführt, weil eine HSQL-Query erwartet wird, die auf die Entity-Klasse geht.

      also from Customer as c where c.lastname="Maier"

      (wobei lastname eine Property der Klasse Customer ist)

      Willst du per Hibernate eine nativen SQL ausführen, so ist nicht "session.createQuery", sondern "session.createSQLQuery" zu nutzen

      Generell ist das Mischen von nativem SQL und die Nutzung von Hibernate zu vermeiden. Du kannst alles was mit nativem SQL erforderlich ist, mit HSQL erledigen
      Christian

      Comment


      • #4
        dimitri hat recht mit beidem was er sagt. Du rufst nie executeUpdate() auf der query auf, darum wird nichts gelöscht. Die Syntax ist korrekt. Eine ID oder ein Primärschlüssel ist nicht erforderlich, noch nichtmal ein Objekt der Klasse Customer. Das DML-style delete geht ja direkt auf die Datenbank. Was anderes wäre es mit session.delete().

        Um die Stringkonkatenierung zu vermeiden benutze am besten named parameters, das Hibernate-Äquivalent zu PreparedStatements.

        Viele Grüße,

        Alwin

        Comment


        • #5
          Eine ID oder ein Primärschlüssel ist nicht erforderlich, noch nichtmal ein Objekt der Klasse Customer.
          Für Hibernate ist keine ID erforderlich?? Das wäre mir neu
          Christian

          Comment


          • #6
            Für Hibernate ist keine ID erforderlich?? Das wäre mir neu
            Für insert, update oder delete im DML-style (wie chris1982 es tut) nicht. Sie sind ja mehr für performante bulk-operations gedacht.

            Schau Dir die Beispiele an. Nirgends eine ID oder ein gemapptes Objekt:

            http://docs.jboss.org/hibernate/stab.../#batch-direct

            Was anderes ist es mit session.delete(), wie bereits erwähnt.

            Comment


            • #7
              Ja sicherlich nicht um die HQL-Abfrage zu tätigen, aber

              liegt es vielleicht daran, dass die ID (also mein hibernate-Primärschlüssel, in den Customer-Objekten so nicht drinsteht, weil ich das irgendwie vergessen hatte),
              braucht in seinen Entitys eine ID um mit Hibernate zu arbeiten:Bsp

              class Test

              @id
              Long id;

              ???
              Christian

              Comment


              • #8
                Hallo,

                das Problem ist schon lange gelöst, alles was mir gefehlt hat, war query.executeUpdate() . Hatte ich aufgrund mangelnder erfahrung einfach vergessen, bzw. war irgendwie davon ausgegangen, dass session.createQuery() schon reicht.
                Zum Thema Prepared Statements: Da ich echt nur so kurze Statements an meine DB absetze, hielt ich den Einsatz von Prepared Staments nicht unbedingt für notwendig. Wer weiß, da hätten bestimmt neue Fallen auf mich gewartet. Also habe ich mich damit zufrieden gegeben, den String so zusammenzusetzen.

                Chris

                @Alwin: Um das Problem mit doppelten Namen zu vermeiden (beim Löschen ein Riesen-Problem) brauche ich meines Erachtens doch die ID, um den eindeutigen Datensatz zu löschen, aber die reicht habe ich mittlerweile gemerkt, dahingehend gebe ich dir recht, dass ich das Objekt nicht brauche, wobei auch Christian meiner Ansicht nach Recht hat, denn zum mappen der Objekte auf die DB will hibernate sehr wohl eine ID als primärschlüssel, bzw. kann ja auch ein zusammengesetzter primärschlüssel sein, wobei mir davon abgeraten wurde, in diversen foren.
                Zuletzt editiert von chris1982; 12.06.2009, 10:50.

                Comment


                • #9
                  Hab gar nicht bemerkt das die Frage schon vom 21.5. war

                  Christian hat recht, zum arbeiten mit Hibernate braucht man eine ID für die Customer-Klasse. Mir ging es doch nur darum das der ursprüngliche gespostete Code nicht lief und das hatte nichts mit der ID zu tun sondern mit dem fehlenden executeUpdate. Du hast doch geschrieben das der Code lief und einfach nichts tut. Wäre also Customer gar nicht gemappt oder eben falsch (ohne ID) hätte es doch eine Fehlermeldung gegeben. Der Code löscht natürlich alle Kunden mit dem übergebenen last name. Ob das gewünscht ist oder nicht, ist eine andere Frage. Wenn man einen ganz bestimmten Kunden löschen will, ist sessionDelete die richtige Wahl und dazu muß das Customer-Objekt erstmal persistent sein und eine ID haben.

                  Zu den PreparedStaments:

                  Das mit den named parameters ist halt eine generelle Empfehlung um nicht irgendwann in die SQL-Injection bzw. HQL-Injection-Fall zu tappen. In Deinem konkreten Fall sieht es nicht danach aus, als bräuchte man sie unbedingt. Eine Frage von gutem/schlechtem Stil und der Gewohnheit.
                  Zuletzt editiert von Alwin Ibba; 12.06.2009, 11:11.

                  Comment


                  • #10
                    Du kannst dir die ID auch von Hibernate erstellen lassen....AutoStrategy...
                    Christian

                    Comment


                    • #11
                      Du kannst dir die ID auch von Hibernate erstellen lassen
                      Sofern man nicht vor hat in einer verteilten Datenbankumgebung zu arbeiten. In Oracle werden hierfür z.B. Sequencen verwendet (und keine Guids) damit verbaut man sich automatisch jegliche Replikation.

                      Dim
                      Zitat Tom Kyte:
                      I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

                      Comment


                      • #12
                        Wenn bsp. der Client die IDs selbst erstellt ersteht das Problem, dass unterschiedliche Clients gleiche IDs erstellen
                        Christian

                        Comment


                        • #13
                          Wenn bsp. der Client die IDs selbst erstellt ersteht das Problem, dass unterschiedliche Clients gleiche IDs erstellen
                          Nur wenn es sich um wiederholbare Werte wie z.B. Zahlen handelt. Möglich wäre aber auch eine Guid (gibt es je nach DB auch datenbankseitig).

                          Dim
                          Zitat Tom Kyte:
                          I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

                          Comment


                          • #14
                            Auch eine GUID ist ein berechneter Wert (MAC-Adresse,Zeit usw.) wo theoretisch di Möglichkeit einer Mehrfdachvergabe vorhanden ist

                            http://de.wikipedia.org/wiki/Guid
                            Christian

                            Comment


                            • #15
                              Theoretisch ist vieles möglich. Trotzdem würd ich eine GUID auch als GUID behandel trotz der Möglichkeit von 1:340.282.366.920.938.463.463.374.607.431.768.211. 456 dass ich eine doppelte in meinem System habe.

                              Ich hab das auch nur angesprochen, weil wir aktuell genau dieses Problem mit einer Anwendung haben.
                              Die Wahrscheinlichkeit, dass ein aus Sequenzen generierter PK auf vier, fünf oder noch mehr Geräten mehrfach erzeugt wird ist eben deutlich höher als die doppelte GUID.

                              Dim
                              Zitat Tom Kyte:
                              I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

                              Comment

                              Working...
                              X