Hibernate: HQL mit Join - Rückgabespalten nur von einer der Tabellen - wie?

Kryptaesthesie

Erfahrenes Mitglied
Hallo,

ich habe einen HQL-Befehl mit einem Join.
Jetzt bekomme ich aber immer eine ClassCastException, weil der HQL-Befehl nicht nur die Spalten des Users, sondern auch die der Tabelle Visit zurückliefert.
Wie grenze ich den Befehl ein, so dass ich nur die des Nutzers bekomme?

Der HQL-Befehl:
Code:
String hql =  "from User u, Visit v where u.id = v.userID and v.concertID = :concertid and u.id in ( select f.userID1 from Friend f where userID2 = :userid )";


Die ganze Methode:
Code:
		String hql =  "from User u, Visit v where u.id = v.userID and v.concertID = :concertid and u.id in ( select f.userID1 from Friend f where userID2 = :userid )";
		
		try {
			begin();
			Query q = getSession().createQuery(hql);
			q.setInteger("userid", userid);
			q.setInteger("concertid", concertid);
			List<User> users = (List<User>) q.list();
			commit();
			return users;
		} catch(HibernateException he) {
			rollback();
			String msg = "Liste der Freunde, die zu einem Konzert gehen, konnte nicht abgerufen werden.";
			logger.error(msg, he);
			throw new DAOException(msg, he);
		}

Danke schon mal für eure Hilfe! :)
Gruß
Gerrit
 
Hallo,

ich häng meine Frage mal an diesen Thread an, weil ich denke, dass das irgendwas damit zu tun haben könnt. Ich bin praktisch "fast" neu mit Hibernate und wollte ein kleines Homeprojekt starten um damit vertraut zu werden.
Ich hab im Moment zwei Tabellen in einer MySQL

Aqua:
aquaID als primarykey
..
..
..
und
Animals:
animalsID als primarykey
fk_aquaID als foreignkey

Ich hab dazu die zwei Klassen

Java:
package de.sb.model;


import java.util.List;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;


@Entity
@Table(name = "Aqua")
public class Aqua {

    @Id
    @GeneratedValue
    @Column(name = "aquaID")
    private Integer id;
    @Column(name = "name")
    private String name;
    @Column(name = "breite")
    private Integer breite;
    @Column(name = "hoehe")
    private Integer hoehe;
    @Column(name = "tiefe")
    private Integer tiefe;
    @Column(name = "volumen")
    private Integer volumen;
  
  
     @OneToMany(mappedBy="aqua")
     private Set<Animals> animal;

    /**
     * Konstruktor
     */
    public Aqua() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getBreite() {
        return breite;
    }

    public void setBreite(Integer breite) {
        this.breite = breite;
    }

    public Integer getHoehe() {
        return hoehe;
    }

    public void setHoehe(Integer hoehe) {
        this.hoehe = hoehe;
    }

    public Integer getTiefe() {
        return tiefe;
    }

    public void setTiefe(Integer tiefe) {
        this.tiefe = tiefe;
    }

    public Integer getVolumen() {
        return volumen;
    }

    public void setVolumen(Integer volumen) {
        this.volumen = volumen;
    }

    public Set<Animals> getAnimal() {
        return animal;
    }

    public void setAnimal(Set<Animals> animal) {
        this.animal = animal;
    }
}

Java:
package de.sb.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "Animals")
public class Animals {
    @Id
    @GeneratedValue
    @Column(name = "animalsID")
    private Integer id;
    @Column(name = "name")
    private String name;
    @Column(name = "latname")
    private String latname;
    @Column(name = "phwertmin")
    private Integer phwertmin;
    @Column(name = "phwertmax")
    private Integer phwertmax;
    @Column(name = "tempmin")
    private Integer tempmin;
    @Column(name = "tempmax")
    private Integer tempmax;
    @Column(name = "abmonat")
    private String abmonat;
    @Column(name = "bismonat")
    private String bismonat;
  

    @ManyToOne
    @JoinColumn(name="fk_aquaID")
    private Aqua aqua;

    /**
     * Konstruktor
     */
    public Animals() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLatname() {
        return latname;
    }

    public void setLatname(String latname) {
        this.latname = latname;
    }

    public Integer getPhwertmin() {
        return phwertmin;
    }

    public void setPhwertmin(Integer phwertmin) {
        this.phwertmin = phwertmin;
    }

    public Integer getPhwertmax() {
        return phwertmax;
    }

    public void setPhwertmax(Integer phwertmax) {
        this.phwertmax = phwertmax;
    }

    public Integer getTempmin() {
        return tempmin;
    }

    public void setTempmin(Integer tempmin) {
        this.tempmin = tempmin;
    }

    public Integer getTempmax() {
        return tempmax;
    }

    public void setTempmax(Integer tempmax) {
        this.tempmax = tempmax;
    }

    public String getAbmonat() {
        return abmonat;
    }

    public void setAbmonat(String abmonat) {
        this.abmonat = abmonat;
    }

    public String getBismonat() {
        return bismonat;
    }

    public void setBismonat(String bismonat) {
        this.bismonat = bismonat;
    }

    public Aqua getAqua() {
        return aqua;
    }

    public void setAqua(Aqua aqua) {
        this.aqua = aqua;
    }
}

Es funktioniert bereits wunderbar, dass man Datensätze in die Tabelle Aqua schreibt und es funktioniert auch wunderbar, dass man Datensätze in die Tabelle Animals schreibt mit dem jeweiligen Fremdschlüssel der Tabelle Aqua. Ich möchte jetzt allerdings in einer View eine Tabelle ausgeben, die mir alle Animals zeigt mit Ihren jeweiligen Aquas und ich bring's einfach nicht fertig, weil mir glaub ich einfach imMo das Verständnis fehlt oder ich auf dem Schlauch stehe. Ich hab gegoogelt, aber irgendwie stoße ich wohl nicht auf die richtige Lösung. Vielleicht kann mir hier wer helfen, wäre super.

Gruß,
Steffi
 
Ich hab jetzt mal einen Ansatz versucht. Und zwar dachte ich mir ich schreibe "einfach" eine Klasse die dann die Werte enhält, die ich von beiden Tabellen haben möchte. Klasse ist folgende:

Java:
/**
*
*/
package de.sb.dto;

import java.util.List;

import de.sb.model.Animals;


public class AquaAnimalsDto {
    private int animalid;
    private int aquaid;
    private String aquaname;
    private String animalname;
    private String animallatname;
    private int animalphwertmin;
    private int animalphwertmax;
    private int animaltempmin;
    private int animaltempmax;
    private String animalabmonat;
    private String animalbismonat;

    public AquaAnimalsDto(int animalid, int aquaid, String aquaname,
            String animalname, String animallatname, int animalphwertmin,
            int animalphwertmax, int animaltempmin, int animaltempmax,
            String animalabmonat, String animalbismonat) {
        this.animalid = animalid;
        this.aquaid = aquaid;
        this.aquaname = aquaname;
        this.animalname = animalname;
        this.animallatname = animallatname;
        this.animalphwertmin = animalphwertmin;
        this.animalphwertmax = animalphwertmax;
        this.animaltempmin = animaltempmin;
        this.animaltempmax = animaltempmax;
        this.animalabmonat = animalabmonat;
        this.animalbismonat = animalbismonat;

    }

    public int getAnimalid() {
        return animalid;
    }

    public void setAnimalid(int animalid) {
        this.animalid = animalid;
    }

    public int getAquaid() {
        return aquaid;
    }

    public void setAquaid(int aquaid) {
        this.aquaid = aquaid;
    }

    public String getAquaname() {
        return aquaname;
    }

    public void setAquaname(String aquaname) {
        this.aquaname = aquaname;
    }

    public String getAnimalname() {
        return animalname;
    }

    public void setAnimalname(String animalname) {
        this.animalname = animalname;
    }

    public String getAnimallatname() {
        return animallatname;
    }

    public void setAnimallatname(String animallatname) {
        this.animallatname = animallatname;
    }

    public int getAnimalphwertmin() {
        return animalphwertmin;
    }

    public void setAnimalphwertmin(int animalphwertmin) {
        this.animalphwertmin = animalphwertmin;
    }

    public int getAnimalphwertmax() {
        return animalphwertmax;
    }

    public void setAnimalphwertmax(int animalphwertmax) {
        this.animalphwertmax = animalphwertmax;
    }

    public int getAnimaltempmin() {
        return animaltempmin;
    }

    public void setAnimaltempmin(int animaltempmin) {
        this.animaltempmin = animaltempmin;
    }

    public int getAnimaltempmax() {
        return animaltempmax;
    }

und dann dachte ich, ich schreibe folgende Methode:


    public void setAnimaltempmax(int animaltempmax) {
        this.animaltempmax = animaltempmax;
    }

    public String getAnimalabmonat() {
        return animalabmonat;
    }

    public void setAnimalabmonat(String animalabmonat) {
        this.animalabmonat = animalabmonat;
    }

    public String getAnimalbismonat() {
        return animalbismonat;
    }

    public void setAnimalbismonat(String animalbismonat) {
        this.animalbismonat = animalbismonat;
    }

}

und dann dachte ich, ich schreib folgende Methode
Java:
public List<AquaAnimalsDto> findallaquaanimals() {
        Session session = this.getSession();
        Criteria criteria = session.createCriteria(Animals.class);
        List<Animals> animal = criteria.list();
        for (Animals a : animal) {
            int animalid = a.getId();
            String animalname = a.getName();
            String animallatname = a.getLatname();
            int animalphwertmin = a.getPhwertmin();
            int animalphwertmax = a.getPhwertmax();
            int animaltempmin = a.getTempmin();
            int animaltempmax = a.getTempmax();
            String animalabmonat = a.getAbmonat();
            String animalbismonat = a.getBismonat();
            Aqua aqua = a.getAqua();
            String aquaname = aqua.getName();
            int aquaid = aqua.getId();
            AquaAnimalsDto aaDto = new AquaAnimalsDto(animalid, aquaid, aquaname, animalname,
                    animallatname, animalphwertmin, animalphwertmax,
                    animaltempmin, animaltempmax, animalabmonat, animalbismonat);
            List<AquaAnimalsDto> aquaanimals = new LinkedList<AquaAnimalsDto>();
            aquaanimals.add(aaDto);

        }
        return aquaanimals;

    }

Der Return funktioniert nicht. Wenn ich das jetzt richtig verstehe müssten ja in der Liste aquaanimals jetzt lauter Objekte der Klasse AquaAnimalsDto sein? Das bringt mich ja glaub auch nicht wirklich weiter. Ich möchte ja eigentlich "einfach" wie oben geschrieben eine Tabelle ausgeben, mit allen Daten aus der Tabelle Animals mit dem jeweiligen Aqua. Ich geh davon aus, dass das ein wirkliches Anfängerproblem ist.

Gruß,
Steffi
 
Ha, es funktioniert. Ich glaub ich steig langsam dahinter, hinter dieses ganze Hibernatezeug. Learning by doing ;-)

Also generell ist gesagt, ich hab die beiden Tabellen ja in einer One-To-Many gemapped. Um nun alle Daten zu erhalten, lag ich mit meinem Versuch wohl nicht so verkehrt. Ich habe wie oben gezeigt eine Klasse gebaut, die die Daten enthält, die ich gerne in "Gesamt" haben möchte. Die oben gezeigte Methode funktioniert wunderbar. Man muss lediglich
Java:
List<AquaAnimalsDto> aquaanimals = new LinkedList<AquaAnimalsDto>();
außerhalb der for-Schleife schreiben (im Nachhinein gesehen, logisch, einfach nur auf dem Schlauch gestanden ;-)
Es wird dann eine Liste aufgebaut mit allen entsprechenden AquaAnimalsDTO-Objekten über welche man ja dann in der view über eine
Java:
<c:foreach></c:foreach>
ausgeben kann.
 
Zurück