tutorials.de Buch-Aktion 02/2012
Like Tree1Danke
  • 1 Beitrag von THMD
ERLEDIGT
JA
ANTWORTEN
4
ZUGRIFFE
730
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Avatar von ThirdKeeper
    ThirdKeeper ThirdKeeper ist offline Mitglied Silber
    Registriert seit
    Sep 2007
    Beiträge
    62
    Hallo!

    System:
    MySQL 5.1.x, JBoss 4.2.3.GA, Hibernate

    Problem:
    Die folgende SQL Abfrage soll eine Liste mit den Typen Long und Double zurück geben, was auch im MySQL Query Browser funktioniert.
    Code :
    1
    2
    3
    4
    
    SELECT i.id, SUM(ROUND(item.aDoubleValue * item.aFloatValue, 2))
    FROM ENTITY_ITEM item, ENTITY i
    WHERE i.id = item.entity_Id
    GROUP BY i.id

    Führe ich nun die Abfrage im PersistenceContainer aus,
    Code :
    1
    2
    
    Query q = entityManager.createNamedQuery("ENTITY_SUM_ROUND_QUERY");
    List <Object [ ]>values = q.getResultList();
    wird die Liste mit den Typen Long, Long zurück gegeben.
    Nehme ich nun den Round(x, d) raus, wird Long, Double zurückgegeben?
    Nehme ich nun SUM(...) raus und lasse ROUND(...) in der Query, wird Long, Integer zurückgegeben?
    Lt. MySQL Reference 5.1 gibt Round(x, d) ein Double Wert zurück.

    Jemand eine Idee?
     
    Gruß Lars

  2. #2
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.724
    Blog-Einträge
    29
    Hallo,

    (nur mal so ne Vermutung... stimmen die Field-typen in deinen Hibernate Mappings mit denen in deinen POJOs überein? Sprich steht im Mapping long und am Pojo Attribut
    auch?
    Gruß Tom
     
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  3. #3
    Avatar von ThirdKeeper
    ThirdKeeper ThirdKeeper ist offline Mitglied Silber
    Registriert seit
    Sep 2007
    Beiträge
    62
    Hab mir schon gedacht, dass so eine Frage kommt.
    Nein es ist ein Double und ein Float Typ im Pojo. So liegen sie auch in der Datenbank (von Hibernate gemapped).

    Wohlgemerkt der erste Typ soll ja Long sein, da es ein ID-Attribut ist. Nur der zweite Wert, der gerundet wird, muss Double sein.
    Hier wird, wie im SELECT versucht aufzuzeigen, ein Double mit einem Float multipliziert.

    Nehmen wir mal an, dass die beiden Attribute Long sind. Warum sollte durch das weglassen von SUM(...), dann Integer zurückgegeben werden?
    Dann müssten die Werte wenn schon Integer sein, sonst würde es ja keinen Sinn machen.

    Es sind definitiv Werder Integer, noch Long Attribute des Pojos, die abgefragt werden.
     
    Gruß Lars

  4. #4
    THMD THMD ist offline Mitglied Gold
    Registriert seit
    Sep 2005
    Beiträge
    122
    Hallo,

    ja es liegt an Hibernate - und an Dir , aber das ist eher ein philosophischer Standpunkt. Aber der Reihe nach.

    Du benutzt den EntityManager und damit JPA. Ich gehe mal davon aus, dass das named query ein "normales" ist, sprich Du arbeitest auf Objekten und mit JPA-QL bzw. HQL. In JPA gibt es keine ROUND() Funktion. Die wird Dir bei Verwendung von Hibernate als Persistence Provider und dem entsprechenden (in Deinem Fall MySQL) Dialect aber trotzdem zur Verfügung gestellt.

    Im MySQL Dialect ist ROUND aber mit einem festen Rückgabewert vom Typ Integer belegt. Das heißt er gibt auch nen Integer zurück, egal was die MySQL da im Hintergrund fabriziert. Damit sollte der Fall
    Zitat Zitat von ThirdKeeper Beitrag anzeigen
    Nehme ich nun SUM(...) raus und lasse ROUND(...) in der Query, wird Long, Integer zurückgegeben?
    klar sein.

    Die SUM() Funktion ist in JPA definiert, und liefert Long für alle ganzzahligen Werte und Double für alle Floatings sowie BigDecimal für BigDecimal und BigInteger für BigInteger zurück - (JPA Spec. 4.8.4). - was dann auch Deine restlichen Fälle erklärt.

    Zitat Zitat von ThirdKeeper Beitrag anzeigen
    wird die Liste mit den Typen Long, Long zurück gegeben.
    Nehme ich nun den Round(x, d) raus, wird Long, Double zurückgegeben?
    SUM(ROUND()) ist SUM() auf Integer, und gibt damit Long zurück. Und im zweiten Fall läuft SUM() auf einen nichtganzahligen Wert und gibt Double zurück.

    Ich hoffe das war einigermassen verständlich.
    Zitat Zitat von ThirdKeeper Beitrag anzeigen
    Jemand eine Idee?
    Entweder Du benutzt Spezialfunktionen wie round (die es ja nicht unbedingt in jeder DB gibt) nicht in normalen JPA-QL bzw. HQL Querries, oder Du bist dir halt der Einschränkungen bewusst. Als Alternative würde ich vorschlagen, Du benutzt einfach ein NamedNativeQuery - dann wird alles in der DB ausgeführt und sollte auch so funktionieren, wie Du es von normalen Abfragen gewohnt bist. Du musst dabei die Abfrage aber "nativ" formulieren - also keine Objektnamen etc. sondern Tabellen und Spaltennamen.

    Du könntest natürlich auch den Dialect bzw. Hibernate erweitern

    Grüße
    THMD
    ThirdKeeper bedankt sich. 
    If Java had true garbage collection, most programs would delete themselves upon execution. (Robert Sewell)

  5. #5
    Avatar von ThirdKeeper
    ThirdKeeper ThirdKeeper ist offline Mitglied Silber
    Registriert seit
    Sep 2007
    Beiträge
    62
    Danke THMD.

    Super Antwort. Habe alles zu 100% verstanden.
    Das bringt mich ein ganzes Stück vorwärts. Nun kann ich eine gute Lösung realisieren.
    Geändert von ThirdKeeper (13.11.09 um 13:42 Uhr)
     
    Gruß Lars

Ähnliche Themen

  1. Datentyp einer Scrollbar von Integer auf Long
    Von MatMagic im Forum Visual Basic 6.0
    Antworten: 0
    Letzter Beitrag: 22.04.09, 23:00
  2. Antworten: 1
    Letzter Beitrag: 28.11.06, 16:59
  3. long double
    Von Oll i im Forum C/C++
    Antworten: 3
    Letzter Beitrag: 22.09.06, 02:49
  4. Antworten: 4
    Letzter Beitrag: 18.06.06, 19:45
  5. String zu long oder Integer Exception
    Von UrsaMajor im Forum C/C++
    Antworten: 4
    Letzter Beitrag: 20.08.05, 11:47