Hibernate "createSQLQuery"

darksmilie

Erfahrenes Mitglied
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?
Code:
String sql = "SELECT hbnUrlaubNumber FROM tblurlaub WHERE hbnMitarbeiterNumber = " + argument;
Query query = session.createSQLQuery(sql);
List list = query.list();
 
"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.

Hibernate3 allows you to specify handwritten SQL (including stored procedures) for all create, update, delete, and load operations.
16.1. Using a SQLQuery

Execution of native SQL queries is controlled via the SQLQuery interface, which is obtained by calling Session.createSQLQuery(). In extremely simple cases, we can use the following form:

List cats = sess.createSQLQuery("select * from cats")
.addEntity(Cat.class)
.list();

This query specified:

*

the SQL query string
*

the entity returned by the query

Here, the result set column names are assumed to be the same as the column names specified in the mapping document. This can be problematic for SQL queries which join multiple tables, since the same column names may appear in more than one table. The following form is not vulnerable to column name duplication:

List cats = sess.createSQLQuery("select {cat.*} from cats cat")
.addEntity("cat", Cat.class)
.list();

This query specified:

*

the SQL query string, with a placeholder for Hibernate to inject the column aliases
*

the entity returned by the query, and its SQL table alias

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

The addJoin() method may be used to load associations to other entities and collections.

List cats = sess.createSQLQuery(
"select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id"
)
.addEntity("cat", Cat.class)
.addJoin("kitten", "cat.kittens")
.list();

A native SQL query might return a simple scalar value or a combination of scalars and entities.

Double max = (Double) sess.createSQLQuery("select max(cat.weight) as maxWeight from cats cat")
.addScalar("maxWeight", Hibernate.DOUBLE);
.uniqueResult();

You can alternatively describe the resultset mapping informations in your hbm files and use them for your queries

List cats = sess.createSQLQuery(
"select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id"
)
.setResultSetMapping("catAndKitten")
.list();
 
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:
Code:
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)
at org.hibernate.loader.Loader.doList(Loader.java:1525)
at org.hibernate.loader.Loader.list(Loader.java:1505)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:103)
at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1343)
at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:151)
at urlaubsplaner.service.DBImpl.AbstractServiceDBImpl.getAllMaterialWhere(AbstractServiceDBImpl.java:280)
at urlaubsplaner.service.DBImpl.UrlaubServiceDBImpl.getMitarbeiterUrlaub(UrlaubServiceDBImpl.java:53)
at urlaubsplaner.service.DBImpl.UrlaubServiceDBImpl.getUrlaub(UrlaubServiceDBImpl.java:119)
at urlaubsplaner.testdaten.testen.main(testen.java:19)
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)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:77)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:68)
at org.hibernate.loader.Loader.getKeyFromResultSet(Loader.java:693)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:282)
at org.hibernate.loader.Loader.doQuery(Loader.java:389)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:208)
at org.hibernate.loader.Loader.doList(Loader.java:1522)
... 8 more
 
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)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:77)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:68)
at org.hibernate.loader.Loader.getKeyFromResultSet(Loader.java:693)

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
 
Mit dem SQLQuery hattest du recht, aber er meckert mir eine Fehlermeldung, die eigentlich nicht sein dürfte.

Code:
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)
at urlaubsplaner.service.DBImpl.UrlaubServiceDBImpl.getMitarbeiterUrlaub(UrlaubServiceDBImpl.java:53)
at urlaubsplaner.service.DBImpl.UrlaubServiceDBImpl.getUrlaub(UrlaubServiceDBImpl.java:119)
at urlaubsplaner.testdaten.testen.main(testen.java:19)

Nunja aber meine Parameter heißen so in der DB und im Source.
 
Besitz die Klasse Urlaub eine Methode setHbnUrlaubNumber(foo bar) ?

Könntest du betreffenden Code mal hier hereinposten? Meine Glaskugel ist gerade verschmutzt ;)
 
Klasse Urlaub:

Code:
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);
	}
}
 
Java:
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
 
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 ;).
 
Zurück