How to catch PSQLException value too long for type character varying - spring

I'm currently testing the data access layer that I've created in spring (PersistenceContext is injected). So I have a stateless EJB that calls a service for example UserService, that inserts/delete/update data in the database.
The service works fine, I was able to insert database. But when I was testing and I input string value that is longer than the set length I got:
javax.transaction.RollbackException: Transaction marked for rollback.
WARNING: DTX5014: Caught exception in beforeCompletion() callback:
javax.persistence.PersistenceException: org.hibernate.exception.DataException: ERROR: value too long for type character varying(20)
Caused by: org.hibernate.exception.DataException: ERROR: value too long for type character varying(20)
Caused by: org.hibernate.exception.DataException: ERROR: value too long for type character varying(20)
My partial code:
#PersistenceContext
protected EntityManager entityManager;
try {
entityManager.persist(e);
} catch(Exception e) {
//log message here
}
Then I've tried everything to catch these errors but I was not able to. Any suggestion on how to resolve the issue?
Thanks,
czetsuya

I've used the following code to find out which error is thrown under your circumstances:
BEGIN;
CREATE TABLE t(v varchar(5));
DO $body$
BEGIN
INSERT INTO t VALUES ('1234567');
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE '!!! %, %', SQLSTATE, SQLERRM;
END;$body$;
ROLLBACK;
You'll see, that error code is 22001, error is named string_data_right_truncation per PostrgeSQL's list of error codes.
I don't know how to catch this error in the Hibernate, but on the PL/pgSQL level you can do it using:
EXCEPTION WHEN SQLSTATE '22001' THEN
-- your code follows
END;
I hope this will help you.

Related

Duplicate Key Exception from Mongo DB does not gets caught

Trying to insert duplicate documents in mongo db with help of mongo repository.
Snippet example:
try{ //insertion of duplicate doc in mongo db } catch(org.springframework.dao.DuplicateKeyException e){ // syso for something else for sake of this example }
I can see the exception getting thrown in console like errorMsg": "E11000 duplicate key error collection
But in code its not coming to catch block at all.
Why this exception cannot be caught in catch block?
Tried catching this exception with all the below exception instances:
org.springframework.dao.DuplicateKeyException,
com.mongodb.MongoWriteException,
Exception.
Since the exception is getting thrown and its evident from the logs it should be caught in catch block.

How to get information about error from SqlExceptionHelper for REST spring application

I have some tables in my database and I want to get information about wrong requests to the database. In case If I'm trying to save entity with wrong foreigns keys, I want to get detail information about these keys.
For example:
2020-03-25 18:37:37.595 ERROR 9788 --- [nio-8090-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: insert or update on table "student" violates foreign key constraint "student_fkey_to_specialty"
Detail: Key (specialtykey)=(2) is not present in table "specialty".
I tried to solve with this code, but I get other information.
could not execute statement; SQL [n/a]; constraint [student_fkey_to_specialty]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
my code:
#PostMapping
public void saveStudent(#RequestBody StudentDTO studentDTO) {
if(studentDTO!=null){
try {
studentService.save(studentDTO);
}catch (Exception|Error e){
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getLocalizedMessage(),e );
}
}
}
Use a loop to iterate to the original exception,
here a example function that does that:
private String getCauseMessage(Throwable t)
Throwable cause = t;
while (t.getCause() != null) {
cause = t.getCause();
}
return t.getLocalizedMessage();
}
As you never know how many exception might be chained together, using a loop is the safest way. If you just use it directly you risk getting a NullPointerException or
not getting the message of the original exception.
Student table is having "student_fkey_to_specialty" which is getting violated. Check on which filed this constraint is and provide the correct value for that field
I solved this problem with this code. This allows getting information about exceptions from the database.
e.getCause().getCause().getLocalizedMessage()

Provide Error Description When Error Occurs in Spring Boot

I m Trying to get Error Code And Error Description whenever Error is thrown From Try Block and as well as Error Class Name.
Whenever is error is thrown from try block i m getting Exception Class Name But I m not getting Exact Description why Error is occuring i need Description.
catch (Exception e) {
System.out.println("########################
e.getMessage()"+e.getMessage());
System.out.println("*******************************
e.getLocalizedMessage()"+e.getLocalizedMessage());
System.out.println("########################## e.getCause()
"+e.getCause());
System.out.println("************************** e.getClass()
"+e.getClass().getConstructors());
System.out.println("************************** e.getClass()
"+e.getClass().getName());
}
I want The Error Description why Error is Producing like if
DataIntegrityViolationException occurs i need on which constraint it just giving DataIntegrityViolationException error.

DB2 SQL Error: SQLCODE=-270 exception thrown by jpa paging item reader

I have created a spring batch service with a item reader, item processor and item writer.I have extended the AbstractPagingItemReader and created my own implementation by the name of JpaPagingItemReader.Now when I ran the batch service the reader reads a fix set of records from db (default page size: 10),processes them and writes them.However on second read it throws me the below exception:
2015-06-25 16:33:00,712 ERROR [jobLauncherTaskExecutor-6][saeedh:120659] org.hibernate.util.JDBCExceptionReporter : DB2 SQL Error: SQLCODE=-270, SQLSTATE=42997, SQLERRMC=63, DRIVER=3.61.65
2015-06-25 16:33:00,712 ERROR [jobLauncherTaskExecutor-6][saeedh:120659] org.hibernate.util.JDBCExceptionReporter : DB2 SQL Error: SQLCODE=-727, SQLSTATE=56098, SQLERRMC=2;-270;42997;63, DRIVER=3.61.65
2015-06-25 16:33:00,712 ERROR [jobLauncherTaskExecutor-6][saeedh:120659] org.hibernate.util.JDBCExceptionReporter : DB2 SQL Error: SQLCODE=-727, SQLSTATE=56098, SQLERRMC=2;-270;42997;63, DRIVER=3.61.65
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute query
com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-270, SQLSTATE=42997, SQLERRMC=63, DRIVER=3.61.65
at com.ibm.db2.jcc.am.ed.a(ed.java:676)
at com.ibm.db2.jcc.am.ed.a(ed.java:60)
at com.ibm.db2.jcc.am.ed.a(ed.java:127)
at com.ibm.db2.jcc.am.gn.c(gn.java:2554)
at com.ibm.db2.jcc.am.gn.d(gn.java:2542)
at com.ibm.db2.jcc.am.gn.a(gn.java:2034)
at com.ibm.db2.jcc.am.hn.a(hn.java:6500)
at com.ibm.db2.jcc.t4.cb.g(cb.java:140)
at com.ibm.db2.jcc.t4.cb.a(cb.java:40)
at com.ibm.db2.jcc.t4.q.a(q.java:32)
at com.ibm.db2.jcc.t4.rb.i(rb.java:135)
I get that this error is probably because there is a CLOB column in the table from where I am reading records but the weird thing is it reads the first batch of 10 records fine,process them and write them but on second time read it throws the above exception.Any suggestions?Below is a snippet from JpaPagingItemReader that I wrote.The override doReadPage method from AbstractPagingItemReader.java.
protected void doReadPage ()
{
setPageSize (10);
// Flush we already have in entity manager
getEntityManager ().flush ();
// clear the entity manager: To read and detach
getEntityManager ().clear ();
Query query = createQuery ().setFirstResult (getPage () * getPageSize ()).setMaxResults (getPageSize ());
if (parameterValues != null)
{
for (Map.Entry<String, Object> me : parameterValues.entrySet ())
{
query.setParameter (me.getKey (), me.getValue ());
}
}
if (results == null)
{
results = new CopyOnWriteArrayList<T> ();
}
else
{
results.clear ();
}
results.addAll (query.getResultList ());
// Detach all objects that became part of persistence context
getEntityManager ().clear ();
}
Any help is highly appreciated as I already behind deadline due to this issue.Please if you think any thing is missing,do let me know and I will update the question.Thanks.
I figured it out.The issue was indeed that we are not allowed to have Clob data as a projection in a scrollable JPA cursor.The first 10 records are read just fine but as soon as It starts to read the second batch it has to move the cursor from 0 to the 11th record.That is when I was getting sql exception.
Simple fix was to remove the CLOB column from the select statement and get it in a separate query where its value is required.That fixed my problem.Thanks.

Identifying database errors and query errors separate in spring

I am writing a RESTful web service using spring 3 and I noticed that when I implemented my DAO's (I am using spring-jdbc for database access), the exceptions that get thrown are pretty generic, so i am not able to identify if the exception occurred because my database is down or my query failed.
sample code:
try {
Q q = jdbcTemplate.queryForObject(MY_QUERY, new Object[]{id}, new MyMapper());
return q;
} catch (DataAccessException e) {
// What is this exception ? database down ? query failed ?
}
Unless I know what exception is this during runtime, I can't send back reasonable error message to service client.
Any help is appreciated. Thanks
You shouldn't be trying to catch every single possible exception; code so that you don't run into the possibility of multiple user or programmer error type exceptions. Generally there are three type of exceptions that occur in every DAO regardless of what you do. (1) your database is down... imo if this is the issue you've got bigger problems. (2) user authentication error which is easy enough to catch and deal with (however you should probably be handling that situation on your RESTful front-end. (3) improper data. If you have bad data, just send the attempted data back and the reason for the exception.
try {
Q q = jdbcTemplate.queryForObject(MY_QUERY, new Object[]{id}, new MyMapper());
return q;
} catch (DataAccessException e) {
throw new DaoException("Could not retrieve q with ID: " + qID, e);
}
The method queryForObject only throws DataAccessException or IncorrectResultSizeDataAccessException. You shouldn't catch exception due to database connection failure at this level. However, in your DAO class, you normally have code to establish the dataSource which can be injected by Spring's IoC container. That part of code will throw exception if the database connection fails. You should catch DB failure exception there.

Resources