# Hibernate "createSQLQuery"



## darksmilie (13. Juni 2006)

Hi
Ich habe ein Problem mit dem Auslesen bestimmter Daten. Ich erstelle mir eine Liste, die dann mit Object[] gefüllt ist, aber wie kann ich die Arrays auslesen?

```
String sql = "SELECT hbnUrlaubNumber FROM tblurlaub WHERE hbnMitarbeiterNumber = " + argument;
Query query = session.createSQLQuery(sql);
List list = query.list();
```


----------



## Christian Fein (13. Juni 2006)

"The addEntity() method associates the SQL table alias with the returned entity class, and determines the shape of the query result set."

Hibernate muss wissen was für Objecte es zusammen bauen soll. Daher: .addEntity("cat", Cat.class)

Dann bekommst du auch eine:
List<Cat> cats; 

Wenn du aus dem Query kein komplettes Object bauen kannst, solltest du JDBC nutzen und dein Object selber zusammenbasteln.



------ orginal hibernate doku zu Nativ SQL


> Chapter 16. Native SQL
> 
> You may also express queries in the native SQL dialect of your database. This is useful if you want to utilize database specific features such as query hints or the CONNECT keyword in Oracle. It also provides a clean migration path from a direct SQL/JDBC based application to Hibernate.
> 
> ...


----------



## lernen.2007 (13. Juni 2006)

Wenn du dich mit Hibernate beschäftigst, kannst mal einen blick in diese Seite werfen.


----------



## darksmilie (13. Juni 2006)

Ich habe noch eine Frage was ist denn der erste Wert bei addEntity()?

Ist das der Klassenname oder der Variablenname?

Mein Code sieht jetzt so aus:

```
String sql = "SELECT hbnUrlaubNumber FROM tblurlaub WHERE hbnMitarbeiterNumber = " + argument;
list = session.createSQLQuery(sql).addEntity("Urlaub", Urlaub.class).list();
ergebnis = (Material[]) list.toArray(arrayPrototype);
```

als Fehlermeldung bekomme ich jetzt:


> org.hibernate.exception.GenericJDBCException: could not execute query
> at org.hibernate.exception.ErrorCodeConverter.handledNonSpecificException(ErrorCodeConverter.java:92)
> at org.hibernate.exception.ErrorCodeConverter.convert(ErrorCodeConverter.java:80)
> at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
> ...


----------



## Christian Fein (13. Juni 2006)

Caused by: java.sql.SQLException: Column 'hbnUrlau1_0_' not found.  <---



> Ich habe noch eine Frage was ist denn der erste Wert bei addEntity()?



Steht doch in der Doku die ich copyundpasted  
"The addEntity() method associates the SQL table alias with the returned entity class, and determines the shape of the query result set." Der Table Alias.



> Caused by: java.sql.SQLException: Column 'hbnUrlau1_0_' not found.
> at com.mysql.jdbc.ResultSet.findColumn(ResultSet.java:2316)
> at com.mysql.jdbc.ResultSet.getInt(ResultSet.java:1287)
> at org.hibernate.type.IntegerType.get(IntegerType.java:26)
> ...



diese 2 Zeilen scheinen interressant:

at org.hibernate.loader.Loader.getKeyFromResultSet(Loader.java:693)

Caused by: java.sql.SQLException: Column 'hbnUrlau1_0_' not found.

Kann nur mutmassen. Aber dein Query sieht mir auch nicht so aus das dieser in konkrete Objecte gemappt werden kann. 
Gibts einen besonderen Grund das du SQL Query einsetzt? 
Nach allem was ich sehe sollte Hibernate Query Language aussreichen um dir die gewünschten Results zu geben. Ein SQL Query zu bauen der dir konkrete Objecte zurückgibt ist nicht unknifflig.

http://www.hibernate.org/hib_docs/reference/en/html/queryhql.html


----------



## darksmilie (13. Juni 2006)

Mit dem SQLQuery hattest du recht, aber er meckert mir eine  Fehlermeldung, die eigentlich nicht sein dürfte.


```
String sql = "SELECT hbnUrlaubNumber FROM tblurlaub WHERE hbnMitarbeiterNumber = " + argument;
list = session.createQuery(sql).setEntity("hbnUrlaubNumber", Urlaub.class).list();
ergebnis = (Material[]) list.toArray(arrayPrototype);
transaction.commit();
```



> java.lang.IllegalArgumentException: Parameter hbnUrlaubNumber does not exist as a named parameter in [SELECT hbnUrlaubNumber FROM tblurlaub WHERE hbnMitarbeiterNumber = 73]
> at org.hibernate.impl.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:380)
> at org.hibernate.impl.AbstractQueryImpl.setEntity(AbstractQueryImpl.java:344)
> at urlaubsplaner.service.DBImpl.AbstractServiceDBImpl.getAllMaterialWhere(AbstractServiceDBImpl.java:280)
> ...



Nunja aber meine Parameter heißen so in der DB und im Source.


----------



## Christian Fein (13. Juni 2006)

Besitz die Klasse Urlaub eine Methode setHbnUrlaubNumber(foo bar) ?

Könntest du betreffenden Code mal hier hereinposten? Meine Glaskugel ist gerade verschmutzt


----------



## darksmilie (13. Juni 2006)

Klasse Urlaub:


```
public class Urlaub extends Material{
	
	private UrlaubNumberDV _UrlaubNumber;
	private DateDV _anfangsdatum;
	private DateDV _enddatum;
	private String _status;
	private int _farbe;
	private MitarbeiterNumberDV _MitarbeiterNummer;
	private int _hbnUrlaubNumber;
	private int _hbnMitarbeiterNumber;
	
	public IdentificatorDV getID() {
		return getUrlaubNumber();
	}
	
	public Urlaub(){
		this(null);
	}
	
	/*
	 * Bekommt ein String, der lediglich dazu dient dein Konstruktor aufzurufen
	 * @param vom Typ String
	 * Setzt eine neu generierte UrlaubNumberDV: UrlaubNumber
	 * Setzt null: MitarbeiterNumber
	 * Setzt null: Anfangsdatum
	 * Setzt null: Enddatum
	 * Setzt ein leeren String: Status
	 * Setzt -1: Farbe
	 */
	public Urlaub(String projekt) {
		this._UrlaubNumber = UrlaubNumberDV.newUrlaubNumberDV();
		this._MitarbeiterNummer = null;
		this._anfangsdatum = null;
		this._enddatum = null;
		this._status    = "";
		this._farbe = -1;
	}
	
	/*
	 * Gibt die UrlaubNumber als String zurück
	 * @return vom Typ String: UrlaubNumber
	 */
	public String getAbteilungNummerString(){
		String nummerStr = String.valueOf(_UrlaubNumber);
		int nummerInt = _UrlaubNumber.getNumber();
		
		if (nummerInt < 10000) {
			if (nummerInt < 1000)	{
				if (nummerInt < 100)	{
					if (nummerInt < 10)	{
						nummerStr = "0000" + nummerStr;
					} else 	{
						nummerStr = "000" + nummerStr;
					}		
				} else 	{
					nummerStr = "00" + nummerStr;
				}
			} else 	{
				nummerStr = "0" + nummerStr;
			}
		}
		return nummerStr;
	}
	
	/*
	 * Gibt die Farbe als int zurück 
	 * @return vom Typ int: Farbe
	 */
	public int getFarbe() {
		return _farbe;
	}
	
	/*
	 * Setzt den Farbe
	 * @param vom Typ int
	 */
	public void setFarbe(int farbe) {
		_farbe = farbe;
	}
	
	/*
	 * Gibt die UrlaubNumber als UrlaubNumberDV zurück 
	 * @return vom Typ UrlaubNumberDV: UrlaubNumber
	 */
	public UrlaubNumberDV getUrlaubNumber() {
		return _UrlaubNumber;
	}
	
	/*
	 * Setzt den UrlaubNumber
	 * @param vom Typ UrlaubNumberDV
	 */
	public void setUrlaubNumber(UrlaubNumberDV number) {
		_UrlaubNumber = number;
	}

	/*
	 * Gibt das Anfangsdatum als DateDV zurück 
	 * @return vom Typ DateDV: Anfangsdatum
	 */
	public DateDV getAnfangsdatum() {
		return _anfangsdatum;
	}

	/*
	 * Setzt den Anfangsdatum
	 * @param vom Typ DateDV
	 */
	public void setAnfangsdatum(DateDV anfangsdatum) {
		_anfangsdatum = anfangsdatum;
	}

	/*
	 * Gibt das Enddatum als DateDV zurück 
	 * @return vom Typ DateDV: Enddatum
	 */
	public DateDV getEnddatum() {
		return _enddatum;
	}

	/*
	 * Setzt den Enddatum
	 * @param vom Typ DateDV
	 */
	public void setEnddatum(DateDV enddatum) {
		_enddatum = enddatum;
	}

	/*
	 * Gibt die MitarbeiterNumber als MitarbeiterNumberDV zurück 
	 * @return vom Typ MitarbeiterNumberDV: MitarbeiterNumber
	 */
	public MitarbeiterNumberDV getMitarbeiterNummer() {
		return _MitarbeiterNummer;
	}

	/*
	 * Setzt den MitarbeiterNumber
	 * @param vom Typ MitarbeiterNumberDV
	 */
	public void setMitarbeiterNummer(MitarbeiterNumberDV mitarbeiterNummer) {
		_MitarbeiterNummer = mitarbeiterNummer;
	}

	/*
	 * Gibt den Status als String zurück 
	 * @return vom Typ String: Status
	 */
	public String getStatus() {
		return _status;
	}

	/*
	 * Setzt den Status
	 * @param vom Typ String
	 */
	public void setStatus(String status) {
		_status = status;
	}
	
	/*
	 * Wandelt die MitarbeiterNumber in ein int Wert für die DB-Anbindung um 
	 * Gibt die MitarbeiterID als int zurück 
	 * @return vom Typ int: MitarbeiterID
	 */
	public int gethbnMitarbeiterNumber(){
	    _hbnMitarbeiterNumber = Integer.parseInt(_MitarbeiterNummer.toString());
		return _hbnMitarbeiterNumber;
	}
	
	/*
	 * Wandelt den int Wert aus der DB wieder in eine MitarbeiterNumberDV um
	 * Setzt die MitarbeiterNumber
	 * @param vom Typ int
	 */
	public void sethbnMitarbeiterNumber(int hbnMitarbeiterNumber){
		_MitarbeiterNummer = MitarbeiterNumberDV.mitarbeiterNumberDV(hbnMitarbeiterNumber);
	}
	
	/*
	 * Wandelt die UrlaubNumber in ein int Wert für die DB-Anbindung um 
	 * Gibt die UrlaubID als int zurück 
	 * @return vom Typ int: UrlaubID
	 */
	public int gethbnUrlaubNumber(){
		_hbnUrlaubNumber = Integer.parseInt(_UrlaubNumber.toString());
		return _hbnUrlaubNumber;
	}
	
	/*
	 * Wandelt den int Wert aus der DB wieder in eine UrlaubNumberDV um
	 * Setzt die UrlaubNumber
	 * @param vom Typ int
	 */
	public void sethbnUrlaubNumber(int hbnUrlaubNumber){
		_UrlaubNumber = UrlaubNumberDV.urlaubNumberDV(hbnUrlaubNumber);
	}
}
```


----------



## Christian Fein (13. Juni 2006)

```
public int gethbnUrlaubNumber(){
		_hbnUrlaubNumber = Integer.parseInt(_UrlaubNumber.toString());
		return _hbnUrlaubNumber;
	}
	
	/*
	 * Wandelt den int Wert aus der DB wieder in eine UrlaubNumberDV um
	 * Setzt die UrlaubNumber
	 * @param vom Typ int
	 */
	public void sethbnUrlaubNumber(int hbnUrlaubNumber){
		_UrlaubNumber = UrlaubNumberDV.urlaubNumberDV(hbnUrlaubNumber);
	}
}
```

hier steckt ein Fehler:
die Get Methode für: hbnUrlaubNumber 
lautet nicht: gethbnUrlaubNumber() sondern getHbnUrlaubNumber
genauso die Set Methode
nicht: sethbnUrlaubNumber sondern setHbnUrlaubNumber


----------



## darksmilie (13. Juni 2006)

hmm, das wars leider auch nicht, ich bekomme immer noch die selbe Fehlermeldung.
ich habe ja schon einige daten aus der datenbank rausgeholt und auch reingeschrieben, nur halt nicht über einen einzelen sql satz. Bisher habe ich mir immer alle daten aus der DB geholt und ganau das möchte ich jetzt bei mir ändern, wozu alle, wenn ich nur ein wert brauche .


----------



## Christian Fein (13. Juni 2006)

darksmilie hat gesagt.:
			
		

> hmm, das wars leider auch nicht, ich bekomme immer noch die selbe Fehlermeldung.



Es ist dennoch falsch  get Methoden müssen den Property mit einem Grossbuchstaben starten lassen.



> ich habe ja schon einige daten aus der datenbank rausgeholt und auch reingeschrieben, nur halt nicht über einen einzelen sql satz. Bisher habe ich mir immer alle daten aus der DB geholt und ganau das möchte ich jetzt bei mir ändern, wozu alle, wenn ich nur ein wert brauche .



Zur ursprünglichen Frage: Wieso mit SQL wenn du doch Hibernate einsetzt? HQL lässt dich das erwünschte genauso erreichen ohne den umweg über SQL.

"select Urlaub as urlaub where urlaub.hbnUrlaubNummer = WERT'.


----------



## darksmilie (13. Juni 2006)

Muß ich denn beim entity darauf achten welcher datentyp das DB-feld hat, da die Methode int und String als Parameter besitzen kann und mein DB-Feld ein int und kein String feld ist, müsste ich Ihm das doch irgentwie sagen, da er dann ja bei der setMethode den falschen übergabewert bekommt oder nicht?

Letzte Fehlermeldung ist immernoch die Aktuelle


----------



## darksmilie (13. Juni 2006)

Ich habe einbischen in der doku geforscht und da steht es so drin wie ich es jetzt habe:


```
list = session.createQuery("SELECT hbnUrlaubNumber FROM tblurlaub WHERE hbnMitarbeiterNumber = ?")
 .setInteger(0,Integer.parseInt(argument)).list();	       
 ergebnis = (Material[]) list.toArray(arrayPrototype);
transaction.commit();
```

Leider funktioniert es immernoch nicht.


> java.lang.IllegalStateException: No data type for node: org.hibernate.hql.ast.IdentNode
> \-[IDENT] IdentNode: 'hbnUrlaubNumber' {originalText=hbnUrlaubNumber}
> 
> at org.hibernate.hql.ast.SelectClause.initializeExplicitSelectClause(SelectClause.java:138)
> ...


----------



## darksmilie (14. Juni 2006)

So wieder paar Schritte weiter, nun bekomme ich eine Fehlermeldung, mit der ich absolut nix anfangen kann, da noch nichtmal google mir da was liefert.

Code:

```
list = session.createQuery("SELECT :urlaub FROM Urlaub WHERE Urlaub.hbnMitarbeiterNumber = ?")
.setEntity("urlaub",Urlaub.class.getDeclaredField("_hbnUrlaubNumber")).setInteger(0,Integer.parseInt(argument)).list();	       
ergebnis = (Material[]) list.toArray(arrayPrototype);
```

Fehler:


> org.hibernate.hql.ast.QuerySyntaxError: unexpected AST node: : [SELECT :urlaub FROM urlaubsplaner.material.Urlaub WHERE Urlaub.hbnMitarbeiterNumber = ?]
> at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:63)
> at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:196)
> at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:130)
> ...


----------

