- Where and how handle spring+hibernate exceptions?
- JPA/Hibernate exception handling
- 6 Answers 6
- Hibernate Exception Handling Example
- Thank you!
- 1. Introduction
- 1.1 Hibernate
- 1.1.1 Hibernate Benefits
- 1.2 Download and Install Hibernate
- 2. Hibernate Exception Handling
- 2.1 Common Hibernate Exceptions and How to Fix Them
- 2.1.1 LazyInitializationException
- 2.1.2 OptimisticLockException
- 6. Conclusion
Where and how handle spring+hibernate exceptions?
im using spring+hibernate for a desktop application. I’m trying to build it with a layered implementation, so i have: GUI layer —call—> Service layer —call—> DAO layer A small example to better exaplain my situation:
// In GUI layer private void actionPerformed(ActionEvent evt) < addUser(); >private void addUser() < // Check gui validation for user inputs if(inputIsValid())< String username=nameText.getText(); String pass=passText.getText(); //Now call service layer userService.createUser(username, pass); // Now here i want to show a message to user like // "Operation successful" or "Operation failed" // or more sofisticated message like "User with same name already exists" >> // Service layer @Transactional public void createUser(String name, String pass) < User user=new User(name, pass); userDao.save(user); >// Another service layer example, @Transactional public boolean createUser(String name, String pass) < User user=new User(name, pass); try< userDao.save(user); >catch(Exception ex) < Log(ex); return false; >return true; // In this case GUI layer can know if save is succesful, but it can't know WHY // the save is failed : some username? DB service shutdown? etc.. >
The problem is: who throw exception and who handle it? I think DAO have to throw first exception, and service layer rethrow it, and finally GUI layer handle exception, so i can show message to user, is this good? There is a way to build some ExceptionHandler using spring? What is the best practice to manage exceptions using spring+hibernate? Thanks.
JPA/Hibernate exception handling
I’m using JPA/Hibernate (a newbie at them). When an exception occur (could be an unique constraint violation) I want to catch it and show some application meaning messages, instead of printing the stack trace. Does Hibernate provide some tool to get info (maybe database independent) about exceptions?
6 Answers 6
HibernateException encapsulates the actual root cause than can provide you enough information for you to generate meaningful user-friendly messages. Read the Exception Handling section of their documentation.
You can do like following. i did that. But offcourse you are using vendor specific code so if you go with a different JPS provider, you will have to change code at several places. At the same time, sometimes its practical when you know you are not gonna change JPA provider easily and user friendly error message is more important
try < . >catch( javax.persistence.PersistenceException ex) < if(ex.getCause() instanceof org.hibernate.exception.ConstraintViolationException) >
You can either catch the general JDBCException :
or you can also catch one of the more specific subclasses of JDBCException such as ConstraintViolationException or JDBCConnectionException :
try < userDao.save(user); //might throw exception >catch(ConstraintViolationException e) < //Email Address already exists >catch(JDBCConnectionException e) < //Lost the connection >
and with the e.getCause() method you can retrieve the underlying SQLException and analyse it further:
Which would print for example: Duplicate entry ‘UserTestUsername’ for key ‘username’
Hibernate Exception Handling Example
This tutorial deals with some of the errors that developers get, while working with Hibernate. Along with the exception or error messages themselves, potential causes of these errors are often listed along with links to additional resources. In this tutorial, we will discuss the Hibernate exceptions.
In order to help you master JPA and database programming with Hibernate, we have compiled a kick-ass guide with all the major Hibernate features and use cases! Besides studying them online you may download the eBook in PDF format!
Thank you!
1. Introduction
1.1 Hibernate
- Object-Relational Mapping or ORM is the programming technique to map application domain model objects to the relational database tables
- Hibernate is a Java based ORM tool that provides a framework for mapping application domain objects to the relational database tables and vice versa. It provides reference implementation of Java Persistence API, that makes it a great choice as an ORM tool with benefits of loose coupling
- The Framework provides the option to map plain old Java objects to traditional database tables with the use of JPA annotations as well as XML based configuration
- The Framework handles the application interaction with the database, leaving the developer free to concentrate more on business logic and solving complex problems
1.1.1 Hibernate Benefits
Hibernate is an ORM implementation. Like many other implementations, it has a numerous number of pros and cons:
- Database Independent : Hibernate is independent of the database engine at the backend. The list of the Hibernate Dialect is provided for connecting whatever database we prefer
- JPA Provider : Java Persistence API (JPA) is a specification. Hibernate is a standard ORM solution and it has a JPA capability. Hence, the use of hibernate would help you leverage all the capabilities of ORM and the JPA in a JPA-specific project
- Built-In Connection Pool : Hibernate has been integrated automatically with the most reliable connection pool implementation i.e. C3P0
- Layered Architecture : Hibernate is a layered architecture, so developers don’t have to be obligated to use everything provided by the framework
1.2 Download and Install Hibernate
You can read this tutorial in order to download and install Hibernate in the Eclipse IDE.
Now, let’s take a look and understand the exception handling in Hibernate framework!
2. Hibernate Exception Handling
- Entered invalid data
- A File that you want to fetch is not found
- Some network problem or Out of Memory run
- IllegalArgumentException : Wrong argument or fail to recognized, or having the incorrect format etc.
- EntityNotFoundException : An Entity was expected but did not match the requirement
- TransactionRequiredException : This operation has to be in a Transaction object
- IllegalStateException : Wrong way of using the Entity Manager
Hibernate works with most of unchecked Hibernate persistence layer exceptions. When Hibernate interacts with the database it throws SQLException . Hibernate provides better handle than the JDBCException .
Developers can use the try and catch block to handle the exceptions. Put the line of code that may cause an exception in a try block and according to that exception put the exception handler in the catch block. Here is an example. We are putting the code of updating in the try block which will be handled by Hibernate Exception in catch block.
package com.hibernate.exception.handling; import com.hibernate.exception.handling.model.Student; import com.hibernate.exception.handling.util.HibernateUtil; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; public class HibernateUpdate < public static void main(String args[]) < Session sessionObj = HibernateUtil.getSessionFactory().openSession(); int roll = 5; Transaction transactionObj = sessionObj.beginTransaction(); Student studentObj = (Student) session.load(Student.class, roll); try < studentObj.setName("Java Code Geek"); studentObj.setCourse("Hibernate"); sessionObj.merge(studentObj); transactionObj.commit(); System.out.println("Update Successfully"); sessionObj.close(); >catch (HibernateException hibernateEx) < try < transactionObj.rollback(); >catch(RuntimeException runtimeEx) < System.err.printf("Couldn’t Roll Back Transaction", runtimeEx); >hibernateEx.printStackTrace(); > finally < if(sessionObj!= null) < sessionObj.close(); >> > >
Note: Any exceptions thrown by the Hibernate framework are FATAL, hence developers have to roll-back the transaction and close the current session object immediately.
2.1 Common Hibernate Exceptions and How to Fix Them
2.1.1 LazyInitializationException
Hibernate throws a LazyInitializationException if you try to access a not initialized relationship to another entity without an active session. You can see a simple example for this in the following code snippet.
EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); Author a = em.find(Author.class, 1L); em.getTransaction().commit(); em.close(); logger.info(a.getFirstName() + " " + a.getLastName() + " wrote "+a.getBooks().size() + " books.");
The best way to fix a LazyInitializationException is to initialize the required relationship in the business tier. But don’t initialize all relationships just because there might be one client out there who needs one of them. For performance reasons, you should only initialize the relationships you need.
2.1.2 OptimisticLockException
- 2 users try to update the same entity at nearly the same point in time
- 1 user performs 2 updates of the same entity, and developers didn’t refresh the entity representation in the client so that the version value wasn’t updated after the first update
Developers can see a test case with 2 concurrent updates in the following code snippet.
// EntityManager and Transaction 1 EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); // EntityManager and Transaction 2 EntityManager em2 = emf.createEntityManager(); em2.getTransaction().begin(); // Update 1 Author a = em.find(Author.class, 1L); a.setFirstName("changed"); // Update 2 Author a2 = em2.find(Author.class, 1L); a2.setFirstName("changed"); // Commit Transaction 1 em.getTransaction().commit(); em.close(); // Commit Transaction 2 try < em2.getTransaction().commit(); Assert.fail(); >catch (RollbackException e) < log.info("2nd transaction failed with an OptimisticLockException"); >em2.close();
This works fine until I try to commit the second transaction and Hibernate checks for concurrent updates of this Author entity. In a real world application, this would, of course, be done by 2 parallel calls of the same method.
That’s all for this post. Happy Learning!!
6. Conclusion
These were my most common Hibernate Exceptions. I suggested some solutions that help me and developers can do the same to handle similar situations. As you have seen, Exceptions and the reason that happen are different things. Some of them only occur during the development and others will hit directly in the production. So better watch out and make sure that you’re familiar with these kind of problems. That’s all for this tutorial and I hope this article served you whatever you were looking for.