title: Catch DataIntegrityViolationException in @Transactional service method
body: <p>I have a REST Spring boot app with Hibernate. For simplicity let's assume this workflow:</p>
  
  <ol>
  <li>Controller handles incoming requests, calls Service methods</li>
  <li>Service methods are <code>@Transactional</code>, do some business logic and call Persistence methods</li>
  <li>Persistence methods are handled by DAO objects, saving stuff into database.</li>
  </ol>
  
  <p>The database has a <code>unique</code> constraint on <code>username</code> of a User. The way I have it working now is this:</p>
  
  <ol>
  <li>Client sends request to Controller</li>
  <li>Controller calls Service</li>
  <li>Service attempts to save an object through DAO. If <code>DataViolationException</code> occurs, Service returns a custom Exception</li>
  <li>Controller catches the custom Exception and sends back appropriate response</li>
  </ol>
  
  <hr>
  
  <p>The pseudocode is this:</p>
  
  <pre><code>public class UserController {
      @RequestMapping("/user")
      public User createUser(...){
          try{
              return userService.createUser(...);
          } catch (UserAlreadyExistsException e){
              // Do some processing and return error message to client
          }
      }
  }
  
  public class UserService {
      @Transactional
      public User createUser(...){
          (...)
          try{
              userDAO.save(newUserObject);
          } catch(DataIntegrityViolationException e){
              throw new UserAlreadyExistsException(username);
          }
      }
  }
  </code></pre>
  
  <p>However, this way I am getting an error when a duplicate user is attempted to be created.</p>
  
  <pre><code>javax.persistence.RollbackException: Transaction marked as rollbackOnly
  </code></pre>
  
  <p><strong>One way to fix this</strong> seems to be to let the <code>DataIntegrityViolationException</code> "bubble" up from the transaction (and not catch it in Service). But that means that the Controller has to handle persistence exceptions and I don't like that.</p>
  
  <p>I prefer if the service threw "understandable" exceptions for the Controller to handle. The service knows what persistence exceptions to expect and when and is able to "translate" the broad <code>DataIntegrityViolationException</code> into a meaningful one.</p>
  
  <p>Is there a way to handle the exceptions this way? I don't particularly like the idea of having a "2-layered service layer" to achieve this. </p>
  
  <hr>
  
  <p>EDIT: Another reason I want to throw my custom Exception is that it is required by the compiler to be caught. I want to enforce the controller to handle all possible exceptions that may occur.</p>