JPA merge doesn't update table - oracle

I'm facing this problem since a week, I hope someone will have a solution for me.
When I make a merge the line in database is not updated.
In the logs, I see the update which is send to Oracle
[EL Finest]: transaction: 2016-02-22 11:14:19.069--UnitOfWork(2109200496)--Thread(Thread[qtp1457417579-16,5,main])--Merge clone with references com.leray.test.User#610b894a
[EL Finer]: transaction: 2016-02-22 11:14:19.069--UnitOfWork(2109200496)--Thread(Thread[qtp1457417579-16,5,main])--begin unit of work flush
[EL Finest]: query: 2016-02-22 11:14:19.07--UnitOfWork(2109200496)--Thread(Thread[qtp1457417579-16,5,main])--Execute query UpdateObjectQuery(com.leray.test.User#610b894a)
[EL Finest]: connection: 2016-02-22 11:14:19.071--ServerSession(1907961337)--Connection(307503319)--Thread(Thread[qtp1457417579-16,5,main])--Connection acquired from connection pool [default].
[EL Finer]: transaction: 2016-02-22 11:14:19.071--ClientSession(925275938)--Connection(307503319)--Thread(Thread[qtp1457417579-16,5,main])--begin transaction
[EL Fine]: sql: 2016-02-22 11:14:19.071--ClientSession(925275938)--Connection(307503319)--Thread(Thread[qtp1457417579-16,5,main])--UPDATE USER SET LIB = ? WHERE (CODE = ?)
bind => [ModifiedLib, COD1]
[EL Finer]: transaction: 2016-02-22 11:14:19.099--UnitOfWork(2109200496)--Thread(Thread[qtp1457417579-16,5,main])--end unit of work flush
[EL Finer]: transaction: 2016-02-22 11:14:19.099--UnitOfWork(2109200496)--Thread(Thread[qtp1457417579-16,5,main])--resume unit of work
[EL Finer]: transaction: 2016-02-22 11:14:19.099--UnitOfWork(2109200496)--Thread(Thread[qtp1457417579-16,5,main])--begin unit of work commit
[EL Finer]: transaction: 2016-02-22 11:14:19.1--ClientSession(925275938)--Connection(307503319)--Thread(Thread[qtp1457417579-16,5,main])--commit transaction
[EL Finest]: connection: 2016-02-22 11:14:19.142--ServerSession(1907961337)--Connection(307503319)--Thread(Thread[qtp1457417579-16,5,main])--Connection released to connection pool [default].
[EL Finer]: transaction: 2016-02-22 11:14:19.143--UnitOfWork(2109200496)--Thread(Thread[qtp1457417579-16,5,main])--end unit of work commit
[EL Finer]: transaction: 2016-02-22 11:14:19.143--UnitOfWork(2109200496)--Thread(Thread[qtp1457417579-16,5,main])--resume unit of work
The same statement in SQL Developper is working fine with the same user.
I have this issue only for one table. I didn't saw something special for this table, a trigger exist but I don't think it could explain my problem.
My code is compile whith Java 1.8 and I'm using theses version JPA and Oracle.
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2</version>
</dependency>
The object generated with Eclipse is quite simple.
package com.leray.test;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
/**
* The persistent class for the User database table.
*
*/
#Entity
#NamedQuery(name="User.findAll", query="SELECT e FROM User e")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private String code;
private String ecran;
private String lib;
private String mdp;
public User() {
}
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
public String getEcran() {
return this.ecran;
}
public void setEcran(String ecran) {
this.ecran = ecran;
}
public String getLib() {
return this.lib;
}
public void setLib(String lib) {
this.lib = lib;
}
public String getMdp() {
return this.mdp;
}
public void setMdp(String mdp) {
this.mdp = mdp;
}
}
My Persistence.xml
<?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="test">
<class>com.leray.test.User</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:#server:1521:siddb"/>
<property name="javax.persistence.jdbc.user" value="****"/>
<property name="javax.persistence.jdbc.password" value="****"/>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<property name="eclipselink.logging.level" value="ALL"/>
<property name="eclipselink.logging.exceptions" value="true"/>
<property name="eclipselink.logging.session" value="true"/>
<property name="eclipselink.logging.thread" value="true"/>
<property name="eclipselink.logging.timestamp" value="true"/>
<property name="eclipselink.logging.connection" value="true"/>
<property name="eclipselink.weaving" value="false"/>
</properties>
</persistence-unit>
</persistence>
My code to call the merge
public final void miseAJour(Evuti evuti) {
em.getTransaction().begin();
em.merge(evuti);
em.flush();
em.getTransaction().commit();
}
Update 2016-02-23 : I've check with the DBA, I saw the update statement on Oracle side but he can't confirm parameters send by eclipselink. I still have no idea to solve the problem.

I've found the root cause and the solution.
The problem come from usage of CHAR instead of VARCHAR.
A quick sample if you want to try.
CREATE TABLE SHORT_TEST
( "CODE" CHAR(10 BYTE),
"LIB" CHAR(30 BYTE)
)
TABLESPACE "DATADBS" ;
INSERT INTO SHORT_TEST VALUES ('LIB1','COD1');
-- 1 line inserted
UPDATE SHORT_TEST SET LIB = 'LIB2' WHERE (CODE = 'COD1');
-- You get 1 line updated
-- Now, try this update which is used by eclipselink
UPDATE SHORT_TEST SET LIB = :1 WHERE (CODE = :2);
-- 0 line updated
When you use a query parameter on a char column, you have to respect the column size. In this sample, if you fill COD1 with six spaces, the query will work.
Unfortunately, I have to work with an old Oracle database and I've no right to change the structure.
By default eclipselink perform a trim on fields.
That's why for Oracle 'COD1' doesn't match with 'COD1 '.
Eclipselink offer a possibility to disabled the automatic trim.
https://wiki.eclipse.org/EclipseLink/FAQ/JPA#How_to_avoid_trimming_the_trailing_spaces_on_a_CHAR_field.3F
So, in my project, I've created a new class with this code.
package com.leray.test;
import org.eclipse.persistence.dynamic.DynamicHelper.SessionCustomizer;
import org.eclipse.persistence.sessions.Session;
public class JpaSessionCustomizer extends SessionCustomizer {
public void customize(Session session) {
session.getLogin().setShouldTrimStrings(false);
}
}
And I've added this property to persistence.xml
<property name="eclipselink.session.customizer" value="com.leray.test.JpaSessionCustomizer"/>
Now Eclipselink return datas with the end spaces and the update in Oracle is working.

Related

Can I use Hibernate Criteria without mapping with Hibernate?

I am using JPA annotations to map entities in my model. However, I found Hibernate Criteria is easy to use and contains less codes to write, so is there some way to use Criteria without mapping with hibernate xml ways? I tried this in my DAO implementation class:
private SessionFactory sFactory; // of type org.hibernate.SessionFactory
....
Session session = sFactory.getCurrentSession();
Criteria criteria = session.createCriteria(BTerminal.class);
But, without hibernate.cfg.xml it's giving nullpointerexception. Of course because it is not injected. But to fill this cfg.xml I have to add mapping xml files, which is not the way I like. So, can I use JPA mapping while using Hibernate Criteria?
I am not using Spring. Still doubt which is easier: write 10+ mapping xmls with all atributes, or to learn more about Spring DaoSupport, or any other ways.
Thanks in advance.
Yes, it will work. You can have JPA annotated entities, while you use Hibernate Criteria to query your entities, instead of JPA Criteria.
I have actually have tested it.
My entity class looks like this:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class TestEntity {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Version
private Long version;
...
}
Then, I have Hibernate config file: hibernate.cfg.xml
<!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="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/test</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="hbm2ddl.auto">create</property>
<property name="show_sql">true</property>
<mapping class="com.test.model.TestEntity" />
</session-factory>
</hibernate-configuration>
Notice, that I still have to list down the entity classes, but I'm not using Hibernate mapping files (hbm.xml). I don't think that Hibernate has support for auto-detection of entity classes, like JPA does (so you still have to list them down even if they are annotated).
Then I have this code as a test, persist entity then retrieve using Hibernate Criteria:
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
TestEntity testEntity = new TestEntity();
testEntity.setName("test");
session.save(testEntity);
List<TestEntity> tests = (List<TestEntity>) session.createCriteria(TestEntity.class).list();
for (TestEntity test : tests) {
System.out.println(test.getName());
}
session.getTransaction().commit();
I have the ff. output in my console:
Hibernate: insert into TestEntity (name, version) values (?, ?)
Hibernate: select this_.id as id1_0_0_, this_.name as name2_0_0_, this_.version as version3_0_0_ from TestEntity this_
test

EJB Maven module using JPA

I have simple maven EJB module using JPA. This is my persistance.xml file
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="Persistence">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<mapping-file>GroupTypes.xml</mapping-file>
<properties>
<property name="hibernate.connection.url" value="jdbc:oracle:thin:#127.0.0.1:1521:E"/>
<property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver"/>
<property name="hibernate.connection.username" value="username"/>
<property name="hibernate.connection.password" value="password"/>
</properties>
</persistence-unit>
</persistence>
I am using EJB Stateless Bean and I am trying to get all attributes from GroupTypes table. This is my bean implementation:
public class TestBean
{
private GroupTypes GroupTypes;
private EntityManagerFactory entityManagerFactory;
private EntityManager entityManager;
#WebMethod (operationName = "justTesting")
public boolean justTesting(#WebParam (name = "param") String value)
{
try
{
entityManagerFactory = Persistence.createEntityManagerFactory("Persistance");
entityManager = entityManagerFactory.createEntityManager();
Query query = entityManager.createQuery("Select name from GroupTypes");
List<AmmEdGroupTypes> result = query.getResultList();
return true;
}
catch(Exception e)
{
e.printStackTrace();
return false;
}
}
}
When I try to invoke this method I get exeption: javax.persistence.PersistenceException: No Persistence provider for EntityManager named Persistance.
My persistance.xml file is placed in folder resources/META-INF/persistance.xml, and if I am not using bean this solution works. Does anydbody have some idea why this is happening only in case when I am using bean?
I am using Intellij 12.1.1, Oracle 11g, Glassfish 3.1 server and JAVA 1.6.
I solved this problem in the following way:
Installed hibernate add-on on glassfish (using glassfish update tool)
On glassfish added jdb connection pool _AmmPool with properties: className, username,password,databaseName and url
On glassfish added jdbc resource jdbc/__amm binding with connection pool _AmmPool
Changed persistence.xml file
Changed pom.xml file
Copied the following libraries into glassfish domains/domain1/lib folder:
antlr-2.7.7
commons-collections-3.2.1,
dom4j-1.6.1,
ejb3-persistence-1.0.2.GA,
hibernate3-maven-plugin-3.0,
hibernate-commons-annotations-4.0.2.Final,
hibernate-core-4.2.2.Final,
hibernate-entitymanager-4.2.2.Final,
javassist-3.15.0-GA,
jta-1.1,
log4j-1.2.17,
oracle-jdbc-11.1.0.6.0-Production+,
slf4j-api-1.6.1
slf4j-log4j12-1.7.5
A also copied these libraries into glassfish/lib floder.
This is my new persistance.xml file: http://pastebin.com/xbEU9Tr0
And this is my pom.xml file: http://pastebin.com/uEjhW36

Can Spring's Embedded HSQL database support the Sybase dialect?

I would like to be able to support the following Sybase 15 ASE syntax in my unit/integration tests that use HSQL...
create table #myTable (value varchar(12) NULL)
HSQL won't recognise how the temp table is named, and baulks at the # character. Instead HSQL would like to use something like this...
create temporary table myTable (value varchar(12) NULL)
or, HSQL also supports most of ANSI-92 SQL according to their docs, however Sybase ASE 15 doesn't have great support for ANSI-92 SQL including how temporary tables are created so the following won't work in Sybase but does in HSQL...
DECLARE LOCAL TEMPORARY TABLE mytable (value varchar(12) NULL)
From everything I have tried I cannot come up with a common syntax that will work with both Sybase and HSQL. Does anyone know of a clean way around this?
The only option I think I have is to create separate DAO's for each database dialect, and control which one is used in the Spring Application Context XML files.
I don't use Hibernate for my datasource, only Spring's JdbcTemplate.
I chose to resolve this issue by implementing a couple of dialect helper classes for my DAO. My goals were to
Execute tests against HSQL databse instead of Sybase
Test as much of my production DAO as possible including the
RowMapper and various SELECT/INSERT statements against the database schema as used in production (but implemented in HSQL)
My DAO ended up looking like this (note the DialectHelper being injected) ...
#Repository
public class MyDaoJdbc MyDao {
private DialectHelper dialectHelper;
/* the meat of the DAO removed for clarity */
#Override
public void createTemporaryTable() {
getSimpleJdbcTemplate().update(dialectHelper.getTempTableCreateSql());
}
#Autowired
public final void setDialectHelper(DialectHelper dialectHelper) {
this.dialectHelper = dialectHelper;
}
}
... my production Spring configuration (spring-db.xml) looks like this and injects the Sybase dialect
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.sybase.jdbc2.jdbc.SybDriver" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="dialectHelper" class="com.acme.myapp.jdbc.DialectHelperSybase" />
... and my Test Spring configuration (spring-db-test.xml) looks like this and injects the HSQL dialect
<jdbc:embedded-database id="dataSource" type="HSQL">
<jdbc:script location="classpath:/resources/schema.sql"/>
<jdbc:script location="classpath:/resources/test-data.sql"/>
</jdbc:embedded-database>
<bean id="dialectHelper" class="com.acme.myapp.dao.jdbc.DialectHelperHsql" />
The DialectHelper classes provide a way of separating out the incompatible database syntax from the DAO ...
public class DialectHelperHsql implements DialectHelper {
#Override
public String getTempTableCreateSql() {
return "create temporary table myTable (value varchar(12) NULL)";
}
}
public class DialectHelperSybase implements DialectHelper {
#Override
public String getTempTableCreateSql() {
return "create table #myTable (value varchar(12) NULL)";
}
}
The Test class itself initialises Spring with the HSQL dialectHelper by loading the file spring-db-test.xml
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={
"classpath:resources/spring-context.xml",
"classpath:resources/spring-db-test.xml"})
#Transactional
#TransactionConfiguration(defaultRollback = true)
public class MyDaoIntegrationHsqlTest {
...
}

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:

How can i call stored procedure using spring with jpa

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.
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.
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();
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

Resources