Spring Jpa Repository crash on insert - spring

I'm trying to implement a repository for refresh JWT tokens and I can't save my token in postgresql.
My entity :
#Entity(name = "refreshtoken")
public class RefreshToken {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
#Column(nullable = false, unique = true)
private String user;
#Column(nullable = false, unique = true)
private String token;
#Column(nullable = false)
private Instant expiryDate;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public Instant getExpiryDate() {
return expiryDate;
}
public void setExpiryDate(Instant expiryDate) {
this.expiryDate = expiryDate;
}
The refresh token is initialised with the right values.
The logs are
Hibernate: select nextval ('hibernate_sequence') Hibernate: insert
into refreshtoken (expiry_date, token, user, id) values (?, ?, ?, ?)
2022-04-08 11:17:22.475 ERROR 24272 --- [nio-8080-exec-1]
o.h.engine.jdbc.spi.SqlExceptionHelper : ERREUR: erreur de syntaxe
sur ou prΦs de ½ user ╗ Positioná: 47 2022-04-08 11:17:22.483 DEBUG
24272 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet :
Failed to complete request:
org.springframework.dao.InvalidDataAccessResourceUsageException: could
not execute statement; SQL [n/a]; nested exception is
org.hibernate.exception.SQLGrammarException: could not execute
statement 2022-04-08 11:17:22.497 ERROR 24272 --- [nio-8080-exec-1]
o.a.c.c.C.[.[.[.[dispatcherServlet] : Servlet.service() for
servlet [dispatcherServlet] in context with path [/xatis-web] threw
exception [Request processing failed; nested exception is
org.springframework.dao.InvalidDataAccessResourceUsageException: could
not execute statement; SQL [n/a]; nested exception is
org.hibernate.exception.SQLGrammarException: could not execute
statement] with root cause
org.postgresql.util.PSQLException: ERREUR: erreur de syntaxe sur ou
prΦs de ½ user ╗ Positioná: 47
I have spring.jpa.hibernate.ddl-auto= update
I created refreshtoken table manualy but I also noticed that after it crashed, all field are created except user.
Any help would be welcome, thanks

Like Manuel pointed out in the comment, user is a reserved word in postgresql

"user" is a reserved keyword for Postgresql

Related

Spring Data Jdbc and Oracle21c

for my latest assignment I'm developing a Spring boot application which will connect with an Oracle 21c database.
The feature of the oracle release we're interested in is the native JSON data type called OSON (reference here: Oracle 21c JSON data type )
I've developed an old fashion DAO approach to accomplish the task, but I would like to use Spring Data JDBC project for the data access layer ideally with minimal extra configuration.
Actually I'm struggling with the mapping of the columns where the OSON type will be stored. After several tries I've obtained the error below following the idea of creating a custom converter for the datatype.
Any suggestion on how to proceed?
pom:
<!-- ORACLE -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11-production</artifactId>
<version>21.1.0.0</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
Entity class:
#Table("T_BUDGET")
#Data #NoArgsConstructor
public class BudgetEntityData {
#Id
private Long id;
#Column("BUDGET")
private JsonObjectWrapper budget;
}
Wrapper used for the converter:
#Data
public class JsonObjectWrapper {
private OracleJsonValue json;
}
Jdbc configuration with custom converter:
#Configuration
#EnableJdbcRepositories
public class JdbcConfig extends AbstractJdbcConfiguration {
//utility object used to centralize the use of OracleJsonFactory, not involved in the problem
private static OracleJsonFactoryWrapper factoryWrapper = new OracleJsonFactoryWrapper(new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false),
new OracleJsonFactory());
#Override
public JdbcCustomConversions jdbcCustomConversions() {
return new JdbcCustomConversions(Arrays.asList(StringToJsonObjectWrapper.INSTANCE,JsonObjectWrapperToString.INSTANCE));
}
#WritingConverter
enum JsonObjectWrapperToString implements Converter<JsonObjectWrapper, String> {
INSTANCE;
#Override
public String convert(JsonObjectWrapper source) {
return source.toString();
}
}
#ReadingConverter
enum StringToJsonObjectWrapper implements Converter<String, JsonObjectWrapper> {
INSTANCE;
#Override
public JsonObjectWrapper convert(String source) {
JsonObjectWrapper jsonObjectWrapper = new JsonObjectWrapper();
OracleJsonValue osonObject = factoryWrapper.createOsonObject(source);
jsonObjectWrapper.setJson(osonObject);
return jsonObjectWrapper;
}
}
}
Error:
2022-04-07 09:47:27.335 DEBUG 24220 --- [nio-8080-exec-1] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2022-04-07 09:47:27.335 DEBUG 24220 --- [nio-8080-exec-1] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT "T_BUDGET"."ID" AS "ID", "T_BUDGET"."BUDGET" AS "BUDGET" FROM "T_BUDGET"]
2022-04-07 09:48:58.006 ERROR 24220 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.data.mapping.MappingException: Could not read value BUDGET from result set!] with root cause
java.sql.SQLException: Invalid column type: getOracleObject not
implemented for class oracle.jdbc.driver.T4CJsonAccessor at
oracle.jdbc.driver.GeneratedAccessor.getOracleObject(GeneratedAccessor.java:1221)
~[ojdbc11-21.1.0.0.jar:21.1.0.0.0] at
oracle.jdbc.driver.JsonAccessor.getObject(JsonAccessor.java:200)
~[ojdbc11-21.1.0.0.jar:21.1.0.0.0] at
oracle.jdbc.driver.GeneratedStatement.getObject(GeneratedStatement.java:196)
~[ojdbc11-21.1.0.0.jar:21.1.0.0.0] at
oracle.jdbc.driver.GeneratedScrollableResultSet.getObject(GeneratedScrollableResultSet.java:334)
~[ojdbc11-21.1.0.0.jar:21.1.0.0.0] at
com.zaxxer.hikari.pool.HikariProxyResultSet.getObject(HikariProxyResultSet.java)
~[HikariCP-3.4.5.jar:na] at
org.springframework.jdbc.support.JdbcUtils.getResultSetValue(JdbcUtils.java:283)
~[spring-jdbc-5.3.8.jar:5.3.8]
I had the very same issue. I fixed it with the RowMapper like this:
Create DTO for the JSON content (JsonObjectWrapper in your case)
#Getter
#Setter
public class JsonContent {
private String code;
private String name;
}
Create entity (BudgetEntityData in your case)
#Data
#Relation( collectionRelation = "persons" )
public class Person {
#Id
private Long id;
private JsonContent content;
}
Create custom RowMapper (probably JdbcConfig in your case)
public class PersonMapper implements RowMapper<Person> {
static ObjectMapper objectMapper = new ObjectMapper();
#Override
public Person mapRow( ResultSet rs, int rowNum ) throws SQLException {
try {
var jsonContent = rs.getBytes( 2 );
var content = objectMapper.readValue( jsonContent, JsonContent.class );
var person = new Person();
person.setId( rs.getLong( 1 ) );
person.setContent( content );
return person;
} catch ( IOException e ) {
throw new RuntimeException( "JSON unmarschalling failed!", e );
}
}
}
Use it in repository (not mentioned in your case) as
#Repository
public interface PersonRepository extends CrudRepository<Person, Long> {
#Query( value = "SELECT id, ctnt FROM PERSON", rowMapperClass = PersonMapper.class )
#Override
List<Person> findAll();
}
Note: you can even simplify it with the spring-data-jpa as:
Define entity
#Entity
#Table( name = Person.TABLE_NAME )
#Data
#Relation( collectionRelation = "persons" )
public class Person {
static final String TABLE_NAME = "PERSON";
#Id
#GeneratedValue
private Long id;
#Column( name = "CTNT" )
#Convert( converter = JsonContentConverter.class )
private JsonContent content;
}
And the converter
public class JsonContentConverter implements AttributeConverter<JsonContent, byte[]> {
static ObjectMapper objectMapper = new ObjectMapper();
#Override
public byte[] convertToDatabaseColumn( JsonContent attribute ) {
try {
return objectMapper.writeValueAsBytes( attribute );
} catch ( JsonProcessingException e ) {
throw new RuntimeException( "JSON marschalling failed!", e );
}
}
#Override
public JsonContent convertToEntityAttribute( byte[] jsonContent ) {
try {
return objectMapper.readValue( jsonContent, JsonContent.class );
} catch ( IOException e ) {
throw new RuntimeException( "JSON unmarschalling failed!", e );
}
}
}

Hibernate not retrieving correct value with SELECT and ORA-00984: column not allowed here error

I am facing two issues here :
Issue 1) I am trying to get the COMPANY_ID using the selectCompanyID variable as shown below. I am storing the value returned into getCompanyID variable.When I tried to print it, as shown in the console output below, it's always printing number 1. However, when I tried to run the actual SQL in the
Oracle SQL developer SQL Worksheeet, I got different number. Because of this I could insert wrong ID in the following INSERT statement where it's
getting used.
Issue 2) As shown in the SQL, I am also getting ORA-00984: column not allowed here error. Noticed, people encountering similar error in the following post :
"column not allowed here" error in INSERT statement
But here I don't have straightforward SQL INSERT statement as the one mentioned in the above post with missing quotes.
public boolean insertEmployeeDetails(Employee employee)
{
logger.debug("Starting EmployeeDaoImpl.insert() .....");
Session session = null;
Transaction tx = null;
boolean status = true;
try {
session = sessionFactory.openSession();
tx = session.beginTransaction();
//The following SELECT query returns a number when I ran it in the Oracle SQL developer SQL worksheet
String selectCompanyID = "SELECT"
+ " VALUE_EMP_ID"
+" FROM "
+ " COMPANY_DATA"
+" WHERE"
+ " testing_id = 1234"
+" AND "
+ " company_employee_id = 3345";
int getCompanyID = session.createSQLQuery(selectCompanyID)
.executeUpdate();
System.out.println("GetCompanyID Test below");
System.out.println(getCompanyID);
String hqlInsert = "INSERT INTO Employee (NAME, IS_CORRECT,IS_WRONG,COMPANY_ID, TRANSACTION_ID,DEFINITION) VALUES"
+ "( SELECT value_emp_id FROM COMPANY_DATA WHERE testing_id = 1234 AND"
+ " company_employee_id = 3345))";
String hqlInsert = "INSERT INTO Employee (NAME,IS_CORRECT,IS_WRONG,COMPANY_ID,TRANSACTION_ID,DEFINITION) VALUES "
+ "("
+employee.getName()+","
+employee.getIsCorrect()+","
+employee.getIsWrong()+","
+getCompanyID+","
+employee.getTransactionId()+","
+employee.getDefinition()+")";
System.out.println("October 3 Checking for hqlInsert");
System.out.println(hqlInsert);
int createdEntities = session.createSQLQuery( hqlInsert )
.executeUpdate();
session.persist(employee);
tx.commit();
System.out.println("October 3 BELOW Checking for hqlInsert");
System.out.println(hqlInsert);
System.out.println("Checking for CreatedEntities");
System.out.println(createdEntities);
} catch(Exception ex) {
tx.rollback();
ex.printStackTrace();
status = false;
} finally {
session.close();
}
logger.debug("Completed EmployeeDaoImpl.insert() .....");
return status;
}
Console :
Hibernate:
SELECT
VALUE_EMP_ID
FROM
COMPANY_DATA
WHERE
testing_id = 1234
AND company_employee_id = 3345
GetCompanyID Test below
1
October 3 Checking for hqlInsert
INSERT INTO Employee (NAME,IS_CORRECT,IS_WRONG,COMPANY_ID,TRANSACTION_ID,DEFINITION) VALUES (Terminology,0,0,1,0,definitionTest)
Hibernate:
INSERT
INTO
Employee
(NAME,IS_CORRECT,IS_WRONG,COMPANY_ID,TRANSACTION_ID,DEFINITION)
VALUES
(Terminology,0,0,1,0,definitionTest)
2017-10-03 11:32:43.753 WARN 5392 --- [nio-8080-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 984, SQLState: 42000
2017-10-03 11:32:43.753 ERROR 5392 --- [nio-8080-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : ORA-00984: column not allowed here
Here is my Entity Class Employee.java is as follows:
package abc.def.mypackage.orm
#Entity
#Table(name = "EMPLOYEE")
public class Employee {
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIsCorrect() {
return isCorrect;
}
public void setIsCorrect(int isCorrect) {
this.isCorrect = isCorrect;
}
public int getIsWrong() {
return isWrong;
}
public void setIsWrong(int isWrong) {
this.isWrong = isWrong;
}
public int getCompanyId() {
return companyId;
}
public void setCompanyId(int companyId) {
this.companyId = companyId;
}
public Integer getTransactionId() {
return transactionId;
}
public void setTransactionId(Integer transactionId) {
this.transactionId = transactionId;
}
public String getDefinition() {
return definition;
}
public void setDefinition(String definition) {
this.definition = definition;
}
#Id
#Column(name = "EMPLOYEE_ID")
#GeneratedValue(strategy = GenerationType.AUTO, generator = "seqgen")
#SequenceGenerator(name = "seqgen", sequenceName = "EMPLOYEE_AUTOINC_SEQ")
private int employeeId;
#Column(name = "NAME")
private String name;
#Column(name = "DEFINITION")
private String definition;
#Column(name = "IS_CORRECT")
private int isCorrect;
#Column(name = "IS_WRONG")
private int isWrong;
#Column(name = "COMPANY_ID")
private int companyId;
#Column(name = "TRANSACTION_ID", nullable = true)
private Integer transactionId;
}
Try putting your String values employee.getName() and employee.getDefinition() in your insert statement into quotes '
String hqlInsert = "INSERT INTO Employee (NAME,IS_CORRECT,IS_WRONG,COMPANY_ID,TRANSACTION_ID,DEFINITION) VALUES "
+ "('"
+employee.getName()+"',"
+employee.getIsCorrect()+","
+employee.getIsWrong()+","
+getCompanyID+","
+employee.getTransactionId()+",'"
+employee.getDefinition()+"')";

hibernate error: java.sql.BatchUpdateException: ORA-00932: inconsistent datatypes: expected NUMBER got BINARY

I am trying to insert a row into a table called Mstrauthorizations. When doing so, I get an error saying Could not execute JDBC batch update. The row is not in the DB - so - I do not see how it could be updating anything at all. The database being used is Oracle. When doing the insert, the keyid is generated with the help of Oracle sequences. My understanding is that the auto-increment of key ids (primary key) is not possible until Oracle 12c. The Mstrauthorizations.java code was generated using Hibernate.
Update: made changes to the Mstrauthorizations.java file and am now getting the following error: java.sql.BatchUpdateException: ORA-00932: inconsistent datatypes: expected NUMBER got BINARY I have initialized the attribuetes/fields of the table in the Mstrauthorizations.java file (so no null values would be passed in) but this is not working.
How can I at least see the column that the hibernate command is complaining about? I am trying to do an insert. Why is an update being performed?
log information
1323 [main] DEBUG org.hibernate.transaction.JDBCTransaction - current autocommit status: false
1327 [main] DEBUG org.hibernate.event.def.AbstractSaveEventListener - generated identifier: 0, using strategy: org.hibernate.id.Assigned
1347 [main] DEBUG org.hibernate.transaction.JDBCTransaction - commit
1348 [main] DEBUG org.hibernate.event.def.AbstractFlushingEventListener - processing flush-time cascades
1349 [main] DEBUG org.hibernate.event.def.AbstractFlushingEventListener - dirty checking collections
1350 [main] DEBUG org.hibernate.event.def.AbstractFlushingEventListener - Flushed: 1 insertions, 0 updates, 0 deletions to 1 objects
1350 [main] DEBUG org.hibernate.event.def.AbstractFlushingEventListener - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
1351 [main] DEBUG org.hibernate.pretty.Printer - listing entities:
1351 [main] DEBUG org.hibernate.pretty.Printer - com.apostx.tables.Mstrauthorizations{employeeid=0, lastlogints=0, reclockts=2007-09-23 10:10:10.0, authorizationsid=0, memo=no value, logonid=joney#mitchell.com, lastname=Mitchell, firstname=Joney, logonpassword=1234567, archived=0, reclockpid=3434, reclockhost=no host, reclocktype=6, active=0, tenantid=5, worktype=0, reclockid=999999}
1368 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
1373 [main] DEBUG org.hibernate.SQL - insert into ORAAPPS.MSTRAUTHORIZATIONS (ACTIVE, ARCHIVED, EMPLOYEEID, FIRSTNAME, LASTLOGINTS, LASTNAME, LOGONID, LOGONPASSWORD, MEMO, RECLOCKHOST, RECLOCKID, RECLOCKPID, RECLOCKTS, RECLOCKTYPE, TENANTID, WORKTYPE, AUTHORIZATIONSID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1482 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - Executing batch size: 1
1496 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
1498 [main] DEBUG org.hibernate.util.JDBCExceptionReporter - Could not execute JDBC batch update [insert into ORAAPPS.MSTRAUTHORIZATIONS (ACTIVE, ARCHIVED, EMPLOYEEID, FIRSTNAME, LASTLOGINTS, LASTNAME, LOGONID, LOGONPASSWORD, MEMO, RECLOCKHOST, RECLOCKID, RECLOCKPID, RECLOCKTS, RECLOCKTYPE, TENANTID, WORKTYPE, AUTHORIZATIONSID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]
java.sql.BatchUpdateException: ORA-00932: inconsistent datatypes: expected NUMBER got BINARY
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10656)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
at com.apostx.hibernate.soverflow.test.TestStack.main(TestStack.java:32)
1498 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 932, SQLState: 42000
1498 [main] ERROR org.hibernate.util.JDBCExceptionReporter - ORA-00932: inconsistent datatypes: expected NUMBER got BINARY
1498 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 932, SQLState: 42000
1498 [main] ERROR org.hibernate.util.JDBCExceptionReporter - ORA-00932: inconsistent datatypes: expected NUMBER got BINARY
1499 [main] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
at com.apostx.hibernate.soverflow.test.TestStack.main(TestStack.java:32)
Caused by: java.sql.BatchUpdateException: ORA-00932: inconsistent datatypes: expected NUMBER got BINARY
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10656)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 8 more
Exception in thread "main" org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
at com.apostx.hibernate.soverflow.test.TestStack.main(TestStack.java:32)
Caused by: java.sql.BatchUpdateException: ORA-00932: inconsistent datatypes: expected NUMBER got BINARY
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10656)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 8 more
TIA
Main program - dbconnection test - working
package com.apostx.dbconnection.test;
import java.sql.*;
public class TestDBConnection {
public static void main(String[] args) {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con=DriverManager.getConnection("jdbc:oracle:thin:#scar:1527:DSV", "ora787", "Huiu7ti" );
Statement statement = con.createStatement();
String sql = "select * from MstrAuthorizations";
ResultSet rs = statement.executeQuery(sql);
while (rs.next()) {
System.out.println("first col " + rs.getInt(1) + " second col " + rs.getString(2));
System.out.println( "login id is " + rs.getString("logonid"));
}
con.close();
}
catch ( Exception e ) {
System.out.println("Database Connection Testing Error : " + e);
e.printStackTrace();
}
}
}
Main Program : Not working
package com.apostx.hibernate.test;
import java.math.BigDecimal;
import org.apache.log4j.BasicConfigurator;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.apostx.tables.Mstrauthorizations;
public class AddRecord {
public static void main(String[] args) {
BasicConfigurator.configure();
// create session factory
SessionFactory factory = new Configuration().
configure("hibernate.cfg.xml").
addAnnotatedClass(Mstrauthorizations.class).
buildSessionFactory();
// create session
Session session = factory.getCurrentSession();
try {
// create object
System.out.println("about to start the work ....");
Mstrauthorizations mstr = new Mstrauthorizations();
BigDecimal tenantid=new BigDecimal(5);
mstr.setFirstname("Joney"); mstr.setLastname("Mitchell");
mstr.setTenantid(tenantid);mstr.setLogonid("joney#mitchell.com");
mstr.setLogonpassword("1234567");mstr.setReclockid(new BigDecimal(999999));
mstr.setReclockhost("no host");mstr.setReclockpid(new BigDecimal(3434));
mstr.setReclocktype(new BigDecimal(6));
// start transaction
session.beginTransaction();
// save info
System.out.println("about to save the data ...");
session.save(mstr);
// commit transaction
session.getTransaction().commit();
System.out.println("All Saved ...");
}
catch ( Exception e ) {
System.out.println("error message is " + e.getLocalizedMessage());
}
finally {
factory.close();
}
}
}
Mstrauthorizations.java
package com.apostx.tables;
// Generated Jun 22, 2017 9:30:03 PM by Hibernate Tools 4.0.0
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
/**
* Mstrauthorizations generated by hbm2java
*/
#Entity
#Table(name = "MSTRAUTHORIZATIONS", schema = "ORAAPPS", uniqueConstraints = {
#UniqueConstraint(columnNames = { "TENANTID", "LOGONID" }),
#UniqueConstraint(columnNames = { "TENANTID", "EMPLOYEEID" }) })
public class Mstrauthorizations {
private BigDecimal authorizationsid = new BigDecimal(0);
private BigDecimal tenantid = new BigDecimal(0);
private BigDecimal employeeid = new BigDecimal(0);
private String logonid = new String("no value");
private String logonpassword = new String("no value");
private BigDecimal worktype = new BigDecimal(0);
private BigDecimal lastlogints = new BigDecimal(0);
private String memo = new String("no value");
private String firstname = new String("no value");
private String lastname = new String("no value");
private BigDecimal active = new BigDecimal(0);
private BigDecimal archived = new BigDecimal(0);
private BigDecimal reclocktype = new BigDecimal(0);
private BigDecimal reclockid = new BigDecimal(0);
private String reclockhost = new String("no value");
private BigDecimal reclockpid = new BigDecimal(0);
private Timestamp reclockts = java.sql.Timestamp.valueOf("2007-09-23 10:10:10.0");
public Mstrauthorizations() {
}
public Mstrauthorizations(BigDecimal authorizationsid) {
this.authorizationsid = authorizationsid;
}
public Mstrauthorizations(BigDecimal authorizationsid, BigDecimal tenantid,
BigDecimal employeeid, String logonid, String logonpassword,
BigDecimal worktype, BigDecimal lastlogints, String memo,
String firstname, String lastname, BigDecimal active,
BigDecimal archived, BigDecimal reclocktype, BigDecimal reclockid,
String reclockhost, BigDecimal reclockpid, Timestamp reclockts) {
this.authorizationsid = authorizationsid;
this.tenantid = tenantid;
this.employeeid = employeeid;
this.logonid = logonid;
this.logonpassword = logonpassword;
this.worktype = worktype;
this.lastlogints = lastlogints;
this.memo = memo;
this.firstname = firstname;
this.lastname = lastname;
this.active = active;
this.archived = archived;
this.reclocktype = reclocktype;
this.reclockid = reclockid;
this.reclockhost = reclockhost;
this.reclockpid = reclockpid;
this.reclockts = reclockts;
}
#Id
#Column(name = "AUTHORIZATIONSID", unique = true, nullable = false, precision = 22, scale = 0)
public BigDecimal getAuthorizationsid() {
return this.authorizationsid;
}
public void setAuthorizationsid(BigDecimal authorizationsid) {
this.authorizationsid = authorizationsid;
}
#Column(name = "TENANTID", precision = 22, scale = 0)
public BigDecimal getTenantid() {
return this.tenantid;
}
public void setTenantid(BigDecimal tenantid) {
this.tenantid = tenantid;
}
#Column(name = "EMPLOYEEID", precision = 22, scale = 0)
public BigDecimal getEmployeeid() {
return this.employeeid;
}
public void setEmployeeid(BigDecimal employeeid) {
this.employeeid = employeeid;
}
#Column(name = "LOGONID", length = 60)
public String getLogonid() {
return this.logonid;
}
public void setLogonid(String logonid) {
this.logonid = logonid;
}
#Column(name = "LOGONPASSWORD", length = 40)
public String getLogonpassword() {
return this.logonpassword;
}
public void setLogonpassword(String logonpassword) {
this.logonpassword = logonpassword;
}
#Column(name = "WORKTYPE", precision = 22, scale = 0)
public BigDecimal getWorktype() {
return this.worktype;
}
public void setWorktype(BigDecimal worktype) {
this.worktype = worktype;
}
#Column(name = "LASTLOGINTS", precision = 22, scale = 0)
public BigDecimal getLastlogints() {
return this.lastlogints;
}
public void setLastlogints(BigDecimal lastlogints) {
this.lastlogints = lastlogints;
}
#Column(name = "MEMO", length = 100)
public String getMemo() {
return this.memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
#Column(name = "FIRSTNAME", length = 30)
public String getFirstname() {
return this.firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
#Column(name = "LASTNAME", length = 30)
public String getLastname() {
return this.lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
#Column(name = "ACTIVE", precision = 22, scale = 0)
public BigDecimal getActive() {
return this.active;
}
public void setActive(BigDecimal active) {
this.active = active;
}
#Column(name = "ARCHIVED", precision = 22, scale = 0)
public BigDecimal getArchived() {
return this.archived;
}
public void setArchived(BigDecimal archived) {
this.archived = archived;
}
#Column(name = "RECLOCKTYPE", precision = 22, scale = 0)
public BigDecimal getReclocktype() {
return this.reclocktype;
}
public void setReclocktype(BigDecimal reclocktype) {
this.reclocktype = reclocktype;
}
#Column(name = "RECLOCKID", precision = 22, scale = 0)
public BigDecimal getReclockid() {
return this.reclockid;
}
public void setReclockid(BigDecimal reclockid) {
this.reclockid = reclockid;
}
#Column(name = "RECLOCKHOST", length = 80)
public String getReclockhost() {
return this.reclockhost;
}
public void setReclockhost(String reclockhost) {
this.reclockhost = reclockhost;
}
#Column(name = "RECLOCKPID", precision = 22, scale = 0)
public BigDecimal getReclockpid() {
return this.reclockpid;
}
public void setReclockpid(BigDecimal reclockpid) {
this.reclockpid = reclockpid;
}
#Column(name = "RECLOCKTS")
public Serializable getReclockts() {
return this.reclockts;
}
public void setReclockts(Timestamp reclockts) {
this.reclockts = reclockts;
}
}
Fixed when following this:
Hibernate: Where do insertable = false, updatable = false belong in composite primary key constellations involving foreign keys?
When data saved to table, ID generated on DB side. Just set "insertable" and "updatable" to false for ID and Timestamp.

java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Object;

I am trying to access list of friends of given username using hibernate. Here is my Service class in which fetchListOfFriends function is used to convert the generic list to an Arraylist of type of FriendsDetails.
#Service
#Transactional
public class DetailsServiceImpl implements DetailsService {
#Autowired
private DetailsDao detailsDao;
#Override
public List<FriendsDetails> fetchListOfFriends(String name) {
#SuppressWarnings("rawtypes")
List listOfFriends=detailsDao.fetchListOfFriends(name);
List<FriendsDetails> friendList= fetchListOfFriendss(listOfFriends);
if(listOfFriends==null){
System.out.println("Empty and null list");
}
System.out.println("size of friendList" + listOfFriends.size());
return friendList;
}
private List<FriendsDetails> fetchListOfFriendss(#SuppressWarnings("rawtypes") List genericList) {
#SuppressWarnings("unchecked")
List<Object> result = (List<Object>) genericList;
Iterator<Object> itr = result.iterator();
List<FriendsDetails> listOfFriend= new ArrayList<FriendsDetails>();
while(itr.hasNext()){
Object[] obj = (Object[]) itr.next();
System.out.println(obj.toString());
String userName = String.valueOf(obj[0]);
FriendsDetails obj1= new FriendsDetails();
obj1.setFriendName(userName);
listOfFriend.add(obj1);
}
return listOfFriend;
}
DetailsDaoImpl.java
#Autowired
private SessionFactory sessionFactory;
#SuppressWarnings("rawtypes")
#Override
public List fetchListOfFriends(String name) {
Session session=sessionFactory.getCurrentSession();
String queryToFetchFriends="Select name,presenceStatus from UserPresence where name in (Select friendName from Friends where name='"+name+"')";
List listOfFriends=session.createSQLQuery(queryToFetchFriends).list();
return listOfFriends;
}
Logs.txt
May 22, 2016 1:24:11 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [springmvc] in context with path [/Testing] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Object;] with root cause
java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Object;
at com.tcs.Service.FriendServiceImpl.searchFriend(FriendServiceImpl.java:61)
at com.tcs.Service.FriendServiceImpl.searchFriend(FriendServiceImpl.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Everything should work correctly.
The problem, obviously, that List listOfFriends is List<String>, not List<Object[]>. It is strange, because of Select name,presenceStatus from UserPresence should return List<Object[]>.
Maybe Spring set an incorrect implementation of #Autowired
private DetailsDao detailsDao;.
Try this code. This should work for List<String>
private List<FriendsDetails> fetchListOfFriendss(List<?> genericList) {
Iterator<?> itr = genericList.iterator();
List<FriendsDetails> listOfFriend = new ArrayList<FriendsDetails>();
while (itr.hasNext()) {
Object obj = itr.next();
String userName = String.valueOf(obj);
System.out.println(userName);
FriendsDetails obj1 = new FriendsDetails();
obj1.setFriendName(userName);
listOfFriend.add(obj1);
}
return listOfFriend;
}

Duplicate id using JPA2 and testing

I'm a bit confused right now :-S
I'm working on a project that uses JPA2, Spring 3.0.5, Hibernate 3.6.0 Final. We have the following code (only relevant classes)
#Entity
public class User extends AbstractEntity implements Serializable {
#Id
#Column(name = "ID", nullable = false, insertable = true, updatable = true, length = 36)
protected String id;
#NotNull
#Size(min = 1, max = 30)
#Column(name = "NAME", length = 30, nullable = false)
private String name;
protected User() {
id = java.util.UUID.randomUUID().toString();
}
#Override
public boolean equals(Object object) {
if (!(object instanceof User)) {
return false;
}
User other = (User) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
}
#Repository("userDao")
public class UserDaoImpl implements UserDao {
#PersistenceContext
private EntityManager em;
public void create(User user) throws PreexistingEntityException, Exception {
try {
em.persist(user);
} catch (EntityExistsException ex) {
logger.error("User " + user + " already exists.", ex);
throw new PreexistingEntityException("User " + user + " already exists.", ex);
} catch (Exception ex) {
logger.error("Exception occurred:", ex);
throw ex;
}
}
}
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "/testDaoContext.xml" })
#TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
#Transactional
public class UserDaoTest {
private UserDao userDao;
#Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
#Test
public void testInsertUserExistingID() {
User user = User.valueOf("1");
user.setFirstname("DUMMY");
user.setName("CRASH");
logger.debug(user);
try {
userDao.create(user);
sessionFactory.getCurrentSession().flush();
} catch (PreexistingEntityException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
logger.debug("id = " + user.getId());
User retrieved = userDao.find(user.getId());
Assert.assertEquals(user.getId(), retrieved.getId());
Assert.assertEquals("DUMMY", retrieved.getFirstname());
Assert.assertEquals("CRASH", retrieved.getName());
}
}
Now, when I run the test (I know, it's not a real unit test) with rollback set to false, I get the following stacktrace:
org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; SQL [insert into PV_UMDB.USERS (CREATION_DT, CREATION_USR, MODIFICATION_USR, MODIFICATION_DT, VERSION, BIRTHDAY, EMAIL, FAX, FIRSTNAME, INTERNAL, MOBILE, NAME, PHONE, PICTURE, STAFF_NO, STAFF_NO_KBC, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]; constraint [PV_UMDB.USERS_PK]; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:637)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:102)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:471)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:515)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:290)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:183)
at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:406)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:90)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:76)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:467)
... 25 more
Caused by: java.sql.BatchUpdateException: ORA-00001: unique constraint (PV_UMDB.USERS_PK) violated
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10768)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 34 more
If I use rollback, then the test passes, which of course is incorrect.
Now, is there a good solution?
Thanks for your help
BB
Peter
You cannot rely on EntityExistsException thrown by persist().
From the javadoc:
EntityExistsException - if the entity
already exists. (If the entity already
exists, the EntityExistsException may
be thrown when the persist operation
is invoked, or the
EntityExistsException or another
PersistenceException may be thrown at
flush or commit time.)
In your case, you get another exception thrown at the commit time. If you replace
sessionFactory.getCurrentSession().flush();
with
em.flush();
you can catch a PersistenceException thrown at the flush time (I'm not sure why it doesn't work the same way with SessionFactory).
The test is to see if a User with an
existing ID is stored, the
PreexistingEntityException is thrown.
The general pattern for checking a exception is:
Junit4: #Test(excpect=ExcpectedException.class), or
JUnit3 or when the easy pattern is not working:
psydocode for JUnit3
try {
invokeExceptionThrowingMethod();
fail("ExceptionX expected");
} catch(ExcpectedException e) {
//expected - do nothing
}
I strongly belive, that if you write your test case more clear, than you will find the bug.
edited
In your case, you need the second variant, because the test must not accept an exception from the first user creation.
#Test
public void testInsertUserExistingID()
//(See my comment to your question about throwing Exception)
throws Exception{
User user = User.valueOf("1");
user.setFirstname("DUMMY");
user.setName("CRASH");
try {
userDao.create(user);
sessionFactory.getCurrentSession().flush();
fail("PreexistingEntityException expected");
} catch (PreexistingEntityException e) {
//Thats what is execpected
}
}
Anyway: axtavt is right

Resources