Error while insertion of data using identity in hibernate - spring

I was facing an issue of inserting data in database where STOCK_ID is identity and STOCK_NAME is string. While inserting the data in database it shows an exception which has mentioned below. Kindly guide me to rectify the issue.
Hibernate: insert into mkyongdb.system.STOCK (STOCK_NAME) values (?)
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not insert: [com.mkyong.user.Stock]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:64)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2345)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2852)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:320)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:713)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:701)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:697)
at com.mkyong.common.App.main(App.java:45)
Caused by: java.sql.SQLSyntaxErrorException: ORA-00926: missing VALUES keyword
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:440)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:837)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:445)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:191)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:523)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1010)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1315)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3576)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3657)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1350)
at org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:57)
... 16 more
Stock.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.mkyong.user.Stock" table="STOCK" catalog="mkyongdb">
<id name="stockId" type="java.lang.Integer">
<column name="STOCK_ID" />
<generator class="identity" />
</id>
<property name="stockName" type="string">
<column name="STOCK_NAME" length="10" />
</property>
<!-- <one-to-one name="stockDetail" class="com.mkyong.user.StockDetail"
cascade="save-update"></one-to-one> -->
</class>
</hibernate-mapping>
hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:#127.0.0.1:1521/xe</property>
<property name="hibernate.connection.username">system</property>
<property name="hibernate.connection.password">admin</property>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="show_sql">true</property>
<property name="hibernate.default_schema">system</property>
<property name="hibernate.hbm2ddl.auto">validate</property>
<mapping resource="com/mkyong/user/DBUser.hbm.xml"></mapping>
<mapping resource="com/mkyong/user/Stock.hbm.xml" />
<mapping resource="com/mkyong/user/StockDetails.hbm.xml" />
</session-factory>
</hibernate-configuration>
Stock.java
package com.mkyong.user;
public class Stock implements java.io.Serializable {
private Integer stockId;
private String stockName;
//private StockDetail stockDetail;
/*public StockDetail getStockDetail() {
return stockDetail;
}
public void setStockDetail(StockDetail stockDetail) {
this.stockDetail = stockDetail;
}*/
public Stock() {
//super();
// TODO Auto-generated constructor stub
}
public Stock(Integer stockId, String stockName) {
super();
this.stockId = stockId;
this.stockName = stockName;
}
public Integer getStockId() {
return stockId;
}
public void setStockId(Integer stockId) {
this.stockId = stockId;
}
public String getStockName() {
return stockName;
}
public void setStockName(String stockName) {
this.stockName = stockName;
}
}
Main.java
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Stock stock = new Stock();
stock.setStockName("sam");
session.save(stock);
session.getTransaction().commit();
Create Query:
CREATE TABLE STOCK
(
STOCK_ID numeric(10) not null,
STOCK_NAME varchar2(50) not null,
CONSTRAINT STOCK_PK PRIMARY KEY (STOCK_ID)
);

I think mkyongdb is your schema which has table named STOCK. So,
use mkyongdb.STOCK instead of mkyongdb.system.STOCK in the
insert statement.
STOCK_ID is a mandatory field and missing in the insert statement.
( By the way, If you use Oracle12c this field may not be included in the insert statement provided that defined as STOCK_ID numeric(10) GENERATED by default on null as IDENTITY in the create table DDL statement directly without need of any other mechanism like trigger. If you have version prior to 12c, a before insert trigger may be created which includes :new.STOCK_ID := seq_stock_id.nextval; statement, where seq_stock_id is a sequence )

Related

my code is executed successfully but data not stored in database with spring and hibernate

when i am going to execute this program.
my program is successfully executed but it doesn't store data in database.
what is the problem in this program.
this is my Employee.java class
package com.spring.demo;
public class Employee {
private int id;
private String name;
private float salary;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getSalary() {
return salary;
}
public void setSalary(float salary) {
this.salary = salary;
}
}
this is my EmployeeDao.java class
package com.spring.demo;
import org.springframework.orm.hibernate5.HibernateTemplate;
public class EmployeeDao {
HibernateTemplate template;
public void setTemplate(HibernateTemplate template) {
this.template = template;
}
public void saveEmployee(Employee e) {
Integer i = (Integer) template.save(e);
if (i > 0) {
System.out.println("Success");
} else {
System.out.println("Not Success");
}
}
public void updateEmployee(Employee e) {
template.update(e);
}
public void deleteEmployee(Employee e) {
template.delete(e);
}
}
this is my Test.java class
package com.spring.demo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext bean = new
ClassPathXmlApplicationContext("spring.xml");
EmployeeDao emp = (EmployeeDao) bean.getBean("obj");
Employee e = new Employee();
e.setId(2);
e.setName("Amit Goyal");
e.setSalary(40000);
emp.saveEmployee(e);
// emp.updateEmployee(e);
bean.close();
}
}
this is my Employee.hbm.xml file
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.spring.demo.Employee" table="amit1234">
<id name="id">
<generator class="assigned"></generator>
</id>
<property name="name"></property>
<property name="salary"></property>
</class>
</hibernate-mapping>
and last this is my spring.xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-
4.2.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe" />
<property name="username" value="system" />
<property name="password" value="tiger" />
</bean>
<bean id="mysessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mappingResources">
<list>
<value>Employee.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle10gDialect
</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="template"
class="org.springframework.orm.hibernate5.HibernateTemplate">
<property name="sessionFactory" ref="mysessionFactory"></property>
<property name="checkWriteOperations" value="false"></property>
</bean>
<bean id="obj" class="com.spring.demo.EmployeeDao">
<property name="template" ref="template"></property>
</bean>
</beans>
In this configuration you are missing transaction management configuration. Use #transactional annotation over your service method.
In you situation data is not committing in the database it just save the data and not commit the data in database.

sequence does not exist error in hibernate

I am working on a java application using JSF and hibernate and the database is oracle.
this is my entity class---------
#Entity
#Table(name="docUpload")
#SequenceGenerator(name="seqGen",sequenceName="docseq")
public class DocDetailsEntity {
#Id
#GeneratedValue(generator="seqGen",strategy=GenerationType.SEQUENCE)
private Integer docId;
private String docName;
private String docDesc;
private String userId;
#Lob
private Clob doc;
table scrips--------
create table docUpload
(
docId number(10) primary key,
docName varchar2(50) not null,
docDesc varchar2(100),
userId varchar2(10) not null,
doc clob not null
);
CREATE SEQUENCE docseq
START WITH 100
INCREMENT BY 1
NOCACHE
NOCYCLE;
hibernate.cfg.xml-----
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- hibernate dialect -->
<property name="hibernate.dialect"> org.hibernate.dialect.OracleDialect </property>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:#xxxxx:1521:xx</property>
<property name="hibernate.connection.username">xxxx</property>
<property name="hibernate.connection.password">xxxx</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<!-- Automatic schema creation (begin) === -->
<property name="hibernate.hbm2ddl.auto">none</property>
<!-- Simple memory-only cache -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- <property name="show_sql">true</property> -->
<mapping class="entity.DocDetailsEntity"/>
</session-factory>
</hibernate-configuration>
but i am getting this error when i am trying to persist the entity into the db
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
.
.
.
.
Caused by: java.sql.SQLSyntaxErrorException: ORA-02289: sequence does not exist
please suggest me a solution
Could you please try to write as
#Table(name="docUpload",schema = "schemaName" )
#SequenceGenerator(name="seqGen",sequenceName="schemaName.seqName")

Hibernate :many to many doesn't work

I'm working on a many to many relationship with hibernate
here are my tables in the data-base :
table : Service
table : Pays
and the join table : service-pays
I have 2 entities : Service and Pays
here is my code:
public class Service implements java.io.Serializable {
private Integer idService;
private String nomService;
private Set<Pays> payses = new HashSet<Pays>();
// getters & setters
....
}
public class Pays implements java.io.Serializable {
private Integer idPays;
private String nomPays;
private Set<Service> services = new HashSet<Service>(0);
// getters & setters
....
}
the mapping fils are:
<hibernate-mapping package="pckg">
<class name="pckg.Service" dynamic-update="true" select-before-update="true" table="service" catalog="database" lazy="false" >
<id name="idService" type="java.lang.Integer">
<column name="id_service" />
<generator class="identity" />
</id>
<property name="nomService" />
<set name="countries" table="service_pays" lazy="true"
inverse="true" cascade="save-update">
<key column="id_service" />
<many-to-many column="id_pays" class="pckg.Pays" />
</set>
</class>
</hibernate-mapping>
<hibernate-mapping package="pckg">
<class name="pckg.Pays" dynamic-update="true" select-before-update="true" table="service" catalog="database" lazy="false" >
<id name="idPays" type="java.lang.Integer">
<column name="id_pays" />
<generator class="identity" />
</id>
<property name="nomPays" />
<set name="ser" table="service_pays" lazy="true"
cascade="save-update" >
<key column="id_pays" />
<many-to-many column="id_service" class="pckg.Service" />
</set>
</class>
</hibernate-mapping>
my methode to save the service:
Pays p1= new Pays("France");
Pays p2=new Pays("Italy");
Set<Pays> list-pays=new HashSet<Pays>();
list-pays.add(p1);
list-pays.add(p2);
Service service=new Service();
service.setNomService("nomService");
service.setCountries(list-pays);
serviceBo.saveService(service);
Here is serviceBo.saveService:
public class ServiceBoImp implements ServiceBo ,Serializable{
ServiceDao serviceDao;
//getter & setter of serviceDao
#Override
public void saveService(Service sited) {
serviceDao.saveService(sited);
}
}
and here is ServiceDao
public class ServiceDaoImp extends HibernateDaoSupport implements ServiceDao ,Serializable {
#Override
public void saveService(ServiceDsite s) {
getHibernateTemplate().setCheckWriteOperations(false);
getHibernateTemplate().save(s);
}
}
the problem is that when i save a service with its Set ,the service is saved correctly but without Pays which means the join table is always empty
I think the problem is that service.getPays() is marked with inverse="true". This means that Hibernate should ignore this side of the relation and track only the other.
Try to move the inverse=true to the other side of the relation, and then the cascade save should work.

HTTP Status 500 - Request processing failed; nested exception is org.hibernate.HibernateException: /hibernate.cfg.xml not found

I am a newbie to Hibernate and Spring and I am getting the above exception while executing the application.
I am trying to fetch the values of a record from the database.
Following is the exception that I am getting :-
message Request processing failed; nested exception is org.hibernate.HibernateException: /hibernate.cfg.xml not found
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.HibernateException: /hibernate.cfg.xml not found
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
root cause
org.hibernate.HibernateException: /hibernate.cfg.xml not found
org.hibernate.util.ConfigHelper.getResourceAsStream(ConfigHelper.java:170)
org.hibernate.cfg.Configuration.getConfigurationInputStream(Configuration.java:1497)
org.hibernate.cfg.Configuration.configure(Configuration.java:1519)
org.hibernate.cfg.Configuration.configure(Configuration.java:1506)
com.me.app.HomeController.handleRequestInternal(HomeController.java:56)
org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.34 logs.
Following are my file :-
POJO
public class Usertable {
int id;
String userName;
String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Controller
//#Controller
public class HomeController extends AbstractController{
//private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
// #RequestMapping(value = "/", method = RequestMethod.GET)
// public String home(Locale locale, Model model) {
// logger.info("Welcome home! The client locale is {}.", locale);
//
// Date date = new Date();
// DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
//
// String formattedDate = dateFormat.format(date);
//
// model.addAttribute("serverTime", formattedDate );
//
// return "home";
// }
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String userName = request.getParameter("userName");
String password = request.getParameter("password");
Usertable user;
Configuration cfg = new Configuration();
SessionFactory sf = cfg.configure().buildSessionFactory();
Session hibsession = sf.openSession();
Transaction tx = hibsession.beginTransaction();
user = (Usertable)hibsession.get(Usertable.class, userName);
System.out.println("UserName is "+ user.getUserName());
System.out.println("Password is "+ user.getPassword());
tx.commit();
hibsession.close();
return new ModelAndView("first","abc","abc");
}
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">tiger</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/contacts</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<mapping resource="Usertable.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Usertable.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 20 Mar, 2013 4:26:30 AM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.me.app.Usertable" table="USERTABLE">
<id name="id" type="java.lang.Integer">
<column name="UserID" />
<generator class="native" />
</id>
<property name="userName" type="java.lang.String">
<column name="UserName" />
</property>
<property name="password" type="java.lang.String">
<column name="UserPassword" />
</property>
</class>
</hibernate-mapping>
servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<!-- <resources mapping="/resources/**" location="/resources/" /> -->
<beans:bean id="urlMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<beans:bean name="/books.htm" class="com.me.app.HomeController" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.me.app" />
</beans:beans>
Kindly help me with this issue.Thanks in advance.!
The thing is you shouldn't instantiate your hibernate configuration in your handle of a request but rather let spring instantiate your session factory and inject it into your controller and retrieve the session from there. Doing this, then you won't have to implement a session factory for each request made to your application.
You can check this question or the official documentation to have details on how to instantiate your session factory via spring.
This will (indirectly) solve your problem.
benzonico and KHY thanks for your inputs. The first mistake that I was doing was I placed the hibernate.cfg.xml inside src/main/java/com/me/app/ which should have been src/main/java/. This worked for me. The next part about TypedMismatch was
user = (Usertable)hibsession.get(Usertable.class, userName);
I was trying to get the String reference from the database which was actually Integer. So that solved the typedMismatchException.
I will definitely try injecting the session factory into my code through spring. Since I am new to this frameworks I learnt a loads while discussing with you and trying the new codes.
Thanks again for your valuable feedback.

Spring JDBC -- bad SQL grammar

I'm working my way through a Spring tutorial, and I'm having a problem in the JDBC section. The code was copied directly from the tutorial itself, and several calls to the database ran correctly before the one that failed. Can anyone help me? Here is my error trace.
Jul 31, 2012 9:40:03 PM org.springframework.jdbc.core.metadata.GenericCallMetaDataProvider processProcedureColumns
WARNING: Error while retrieving metadata for procedure columns: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: FUNCTION getrecord does not exist
Jul 31, 2012 9:40:03 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
Jul 31, 2012 9:40:03 PM org.springframework.jdbc.support.SQLErrorCodesFactory <init>
INFO: SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase] Exception in thread "main" org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback; bad SQL grammar [{call getrecord()}]; nested exception is com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: FUNCTION getrecord does not exist
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:98)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:969)
at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1003)
at org.springframework.jdbc.core.simple.AbstractJdbcCall.executeCallInternal(AbstractJdbcCall.java:391)
at org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute(AbstractJdbcCall.java:354)
at org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SimpleJdbcCall.java:181)
at com.tutorialspoint.StudentJDBCTemplate.getStudent(StudentJDBCTemplate.java:32)
at com.tutorialspoint.MainApp.main(MainApp.java:29)
Caused by: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: FUNCTION getrecord does not exist
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:936)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2985)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3277)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3206)
at com.mysql.jdbc.Statement.executeQuery(Statement.java:1232)
at com.mysql.jdbc.DatabaseMetaData.getCallStmtParameterTypes(DatabaseMetaData.java:1607)
at com.mysql.jdbc.DatabaseMetaData.getProcedureColumns(DatabaseMetaData.java:4034)
at com.mysql.jdbc.CallableStatement.determineParameterTypes(CallableStatement.java:709)
at com.mysql.jdbc.CallableStatement.<init>(CallableStatement.java:513)
at com.mysql.jdbc.Connection.parseCallableStatement(Connection.java:4583)
at com.mysql.jdbc.Connection.prepareCall(Connection.java:4657)
at com.mysql.jdbc.Connection.prepareCall(Connection.java:4631)
at org.springframework.jdbc.core.CallableStatementCreatorFactory$CallableStatementCreatorImpl.createCallableStatement(CallableStatementCreatorFactory.java:167)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:947)
... 6 more
Here is the section of my main application where the problem occurs, and I've marked the line in question.
System.out.println("----Listing Record with ID = 2 -----");
// Error occurs in next line
Student student = studentJDBCTemplate.getStudent(2);
System.out.print("ID : " + student.getId());
System.out.print(", Name : " + student.getName());
System.out.println(", Age : " + student.getAge());
StudentJDBCTemplate has these two variables.
private DataSource dataSource;
private SimpleJdbcCall jdbcCall;
StudentJDCBTemplate sets the data source like this, and this may be the genesis of the problem, since I cannot figure out what getRecord refers to.
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
this.jdbcCall = new SimpleJdbcCall(dataSource)
.withProcedureName("getRecord");
}
The problem occurs in this method of StudentJDBCTemplate.
public Student getStudent(Integer id) {
SqlParameterSource in = new MapSqlParameterSource().addValue("in_id",
id);
Map<String, Object> out = jdbcCall.execute(in);
Student student = new Student();
student.setId(id);
student.setName((String) out.get("out_name"));
student.setAge((Integer) out.get("out_age"));
return student;
}
Here is my Beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd "> <!-- Initialization for data source -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/TEST" />
<property name="username" value="root" />
<property name="password" value="password" />
</bean> <!-- Definition for studentJDBCTemplate bean -->
<bean id="studentJDBCTemplate" class="com.tutorialspoint.StudentJDBCTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
For what it's worth, here is my Student class.
package com.tutorialspoint;
public class Student {
private Integer age;
private String name;
private Integer id;
public void setAge(Integer age) {
this.age = age;
}
public Integer getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
}
Following your tutorial, you missed the creation of the getRecord stored procedure:
DELIMITER $$
DROP PROCEDURE IF EXISTS `TEST`.`getRecord` $$
CREATE PROCEDURE `TEST`.`getRecord` (
IN in_id INTEGER,
OUT out_name VARCHAR(20),
OUT out_age INTEGER)
BEGIN
SELECT name, age
INTO out_name, out_age
FROM Student where id = in_id;
END $$
DELIMITER ;
You are trying to execute Stored Procedure "getrecord". Which does not exist or not compiled properly in database. Try to execute first through SQL Client at database side.
Procedure should match with signature as 2 out parameter and one input parameter.
Caused by: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: FUNCTION getrecord does not exist.. So check it once.. Create getrecord function and try once..
Just in case that someone come across this in 2017, here is necessary change to that old tutorial if you are using MySQL Connector version 6.x instead of 5.x
In Beans.xml this line should be:
<property name="url" value="jdbc:mysql://localhost:3306/test?nullNamePatternMatchesAll=true" />
instead of:
<property name="url" value="jdbc:mysql://localhost:3306/test />
SQL error is quite misleading claiming that "out_name" parameter in not defined.
This is due to change in MySQL Connector from version 5.x to 6.x as commented here
Original SO answer is here:

Resources