5

Am new to SPRING with JPA techniques.

am trying to call the stored procedure which is written in mysql 5. when i am trying to get the data using stored procedure call it spewing exception.

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.QueryException: query must begin with SELECT or FROM: call [call st_proc_getusers()]; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: query must begin with SELECT or FROM: call [call st_proc_getusers()]

my persistence.xml is

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit  name="SPT3" transaction-type="RESOURCE_LOCAL">
            <mapping-file>META-INF/persistence-query.xml</mapping-file>
            <class>com.spt3.pojo.Users</class>
            <properties>
                    <property name="hibernate.dialect" value=">org.hibernate.dialect.MySQLDialect" />
                    <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/spring_security" />
                    <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
                    <property name="hibernate.connection.username" value="user" />
                    <property name="hibernate.connection.password" value="pass" />
                    <property name="cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
                    <property name="hibernate.max_fetch_depth" value="3"/>
                    <property name="hibernate.query.factory_class" value="org.hibernate.hql.classic.ClassicQueryTranslatorFactory"/>
                    <property name="hibernate.query.substitutions" value="true 1, false 0"/>
                    <property name="hibernate.show_sql" value="true"/>
                    <property name="hibernate.hbm2ddl.auto" value="create"/>
            </properties>
    </persistence-unit>
</persistence>

i tried code is

package com.spt3.dao;

import com.spt3.pojo.Users;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import org.springframework.orm.jpa.JpaCallback;
import org.springframework.orm.jpa.support.JpaDaoSupport;
import org.springframework.transaction.annotation.Transactional;


@Transactional
public class JpaUsersDao extends JpaDaoSupport {

    public void getResultsByStoredProcedure() {       
        List list=(ArrayList)getJpaTemplate().execute(new JpaCallback() {
            public List doInJpa(EntityManager em) throws PersistenceException {
                javax.persistence.Query query=em.createQuery("call st_proc_getusers()"); // Here the procedure call 
                return query.getResultList(); // returning result list
            }
        });        
    }

}

Actually i don't know how to call the stored procedure using jpa template.

How can i call stored procedure from spring JPA?

please give the solution to get out from this issue.

skaffman
  • 398,947
  • 96
  • 818
  • 769
Mohan
  • 877
  • 10
  • 20
  • 32

3 Answers3

4

Use EntityManager.createNativeQuery() instead. I don't think it's possible to call a stored procedure through a JPA query.

public List doInJpa(EntityManager em) throws PersistenceException {
  javax.persistence.Query query=em.createNativeQuery("call st_proc_getusers()"); 
  return query.getResultList(); 
}

You could also use @NamedNativeQuery.

Xavi López
  • 27,550
  • 11
  • 97
  • 161
  • i tried your idea sir, but iam getting another exception like org.springframework.orm.hibernate3.HibernateSystemException: No Dialect mapping for JDBC type: -1; nested exception is org.hibernate.MappingException: No Dialect mapping for JDBC type: -1 do i need to put any configuration in persistence.xml? – Mohan Oct 25 '11 at 09:43
  • am using mysql5 andd also i have specified the dialect information in persistence.xml file. this original post having the persistence.xml file configuration. – Mohan Oct 25 '11 at 09:53
  • Being `st_proc_getusers` a stored procedure, it cannot have any return type. You should be executing it by means of `query.list()`. Are you passing any arguments to it? – Xavi López Oct 25 '11 at 10:00
  • there is no arguments for st_proc_getusers procedure sir. – Mohan Oct 25 '11 at 10:05
  • Actually the problem is, my database table contains 4 columns. lets say user_id,username,password & enabled. the datatype for those columns are int,varchar,TEXT,int. when i try to get all the fields using select query (select * from users). it give the exception. but when i exclude the password field like (select user_id,username,enabled from users ) it works perfect. why TEXT based type field are not supporting sir?. – Mohan Oct 25 '11 at 10:39
  • Take a look at this question, that addresses this specific problem by defining a custom dialect (maybe you should extend `org.hibernate.dialect.MySQLDialect`): [Hibernate SQL QUERY, problem with TEXT data type in mysql](http://stackoverflow.com/q/7192190/851811) – Xavi López Oct 25 '11 at 11:17
  • Also, take a look at this Hibernate JIRA issue: [HHH-1483](https://hibernate.onjira.com/browse/HHH-1483). This should have been fixed in hibernate-core 3.5.0.Beta-1 and later per [HHH-3892](https://hibernate.onjira.com/browse/HHH-3892). – Xavi López Oct 25 '11 at 11:24
  • Is there any way I could make the queries inside a Stored Procedure execute inside the context of a Spring Transaction? Currently no additional transaction is opened when I'm inside the stored procedure code, and the reads of the SP read the information as it looked before the Spring transaction started. – Romeo Jul 23 '12 at 15:30
2

JPA 2.1 introduced support for stored procedures. You might want to give it a try instead of a native queries.

http://docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html#createStoredProcedureQuery%28java.lang.String%29

JanM
  • 1,385
  • 1
  • 15
  • 25
2

Calling a stored procedure means executing some SQL statement. You can't do that with with a JPQL query (what you get in your code when you do em.createQuery(...)). You must create a native query that allows you to send native SQL to the database, execute it and get the results:

 String query = "call st_proc_getusers(?)";
 NativeQuery nq = em.createNativeQuery(query);
 //the following line is necessary only if your stored procedure accepts a parameter:
 nq.setParameter(1, "paramValue");
 List<?> results = em.createNativeQuery(query).getResultList();
Shivan Dragon
  • 15,004
  • 9
  • 62
  • 103