Hallo Community
Ich habe folgendes Problem, welches sich für mich ziemlich hackelig anhöhrt, aber wohlmöglich recht einfach zu lösen ist.
Beim Programmieren einer Webanwendung nutze ich als Datenbank PostgreSQL 9.0 als Framework Spring 3.0.2 und Hibernate für den Zugriff Datenbank.
Nun bietet sich mir folgendes Problem:
Ich rufe eine sogenannte Stored Procedure auf die in der Datenbank implementiert ist. Diese liefert einen Array von Dates zurück. Der Rückegabewert ist auf jeden Fall vorhanden, ich habe die Prozedur testweise schon direkt in der Datenbank ausgeführt.
Code:
-- Function: get_planned_date(integer, integer, character varying)
-- DROP FUNCTION get_planned_date(integer, integer, character varying);
CREATE OR REPLACE FUNCTION get_planned_date(part_number integer, bom_id integer, username character varying)
RETURNS date[] AS
$BODY$
DECLARE
planned_date date[];
duration integer;
next_planned_date date;
schedule_id integer;
BEGIN
FOR schedule_id IN 1 .. 30
LOOP
IF schedule_id = 21 THEN
SELECT get_duration(part_number,29) INTO duration;
ELSE
IF schedule_id = 22 THEN
SELECT get_duration(part_number,30) INTO duration;
ELSE
IF schedule_id = 23 THEN
--date for this id is inserted manually
ELSE
SELECT get_duration(part_number,schedule_id) INTO duration;
END IF;
END IF;
END IF;
SELECT get_next_planned_date(bom_id,username,part_number,schedule_id) INTO next_planned_date;
planned_date[schedule_id] := next_planned_date - duration;
END LOOP;
RETURN planned_date;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION get_planned_date(integer, integer, character varying) OWNER TO postgres;
Der Aufruf der Prozedur sieht wie folgt aus:
Code:
query = "SELECT get_planned_date(:partnumber, :bomID, :username);";
this.sessionFactory.getCurrentSession().createSQLQuery(query).setInteger("partnumber",partsTasks.getPk().getParts().getPartnumber()).setInteger("bomID", partsTasks.getPk().getParts().getBomId()).setString("username",partsTasks.getUsername()).uniqueResult();
Als Exception wird mir hier "org.hibernate.MappingException: No Dialect mapping for JDBC type: 2003" geworfen. Bei diesem Typ handelt es sich um folgenden:
Code:
/**
* The constant in the Java programming language, sometimes referred to
* as a type code, that identifies the generic SQL type
* <code>ARRAY</code>.
* @since 1.2
*/
public final static int ARRAY = 2003;
Nun habe ich auch schon andere Varianten ausprobiert wie z.B. list() anstatt uniqueResult(), der Fehler bleibt aber der gleiche.
Ich muss also Hibernate mitteilen, um welchen Typ es sich handelt, nun bin ich kürzlich auf eine Variante gestoßen, bei der ich die Methode addScalar nutzen kann.
Code:
this.sessionFactory.getCurrentSession().createSQLQuery(query).addScalar("get_planned_date(:partnumber, :bomID, :username)", Hibernate.CHARACTER_ARRAY).setInteger("partnumber",partsTasks.getPk().getParts().getPartnumber()).setInteger("bomID", partsTasks.getPk().getParts().getBomId()).setString("username", partsTasks.getUsername()).uniqueResult();
Also entweder ich benutzte diese falsch oder es gibt eine andere Möglichkeit, wobei ich mir auch nicht mit dem Typ, den man in dieser auswählen kann sicher bin. Das einzige was mir am sinnigsten erscheint ist Hibernate.CHARACTER_ARRAY.
Das zweite Problem bei dieser Methode ist, dass man einen String als Parameter für diesen Typ im Query angeben muss. Da ich aber eine Prozedur und keine Spalte anspreche tritt folgenden Exception auf:
org.postgresql.util.PSQLException: The column name get_planned_date(:partnumber, :bomID, :username) was not found in this ResultSet.
Habe ich etwas übersehen oder eventuell die Methoden falsch genutzt, gibt es noch andere Möglichkeiten?