Intercept Exception

7

I'm using Demoiselle in my application, but it does not come out very well in one respect. In an association between two or more entities, deleting throws an exception. With the exception handling available in Demoiselle, I've created a method to catch this exception, but we're not getting it.

Follow the example code.

@Entity
public class Bookmark implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Column
    private String description;
    @Column
    private String link;

And the Client class:

@Entity
public class Cliente implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Column
    private String name;
    @ManyToOne
    @JoinColumn(name = "bookmark_id", referencedColumnName = "id", nullable = false)
    private Bookmark bookmark;

Through this, we can see that the Client has a many-to-one association with Bookmark. So when registering a customer I should add a bookmark to it. The problem occurs when you delete a bookmar that has reference on a client. It returns me the following error.

  

Caused by: javax.persistence.RollbackException: Error while committing   the transaction at   org.hibernate.ejb.TransactionImpl.commit (TransactionImpl.java:92) at   br.gov.frameworkdemoiselle.transaction.JPATransaction.commit (JPATransaction.java:121)     ... 60 more Caused by: javax.persistence.PersistenceException:   org.hibernate.exception.ConstraintViolationException: could not   execute statement at   org.hibernate.ejb.AbstractEntityManagerImpl.convert (AbstractEntityManagerImpl.java:1387)     at   org.hibernate.ejb.AbstractEntityManagerImpl.convert (AbstractEntityManagerImpl.java:1310)     at org.hibernate.ejb.TransactionImpl.commit (TransactionImpl.java:80)     ... 61 more Caused by:   org.hibernate.exception.ConstraintViolationException: could not   execute statement

     

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:   Can not delete or update parent row: a foreign key constraint fails   (% with%.% of%, CONSTRAINT    db_estacionamento FOREIGN KEY ( cliente ) REFERENCES    FK_ht5q4yqv47muisi25vq14yw2u ( bookmark_id ))

To try to handle this error, in the BookmarkEditMB class I created a method to catch this exception. But specifically this case, you can not capture it.

@ViewController
@PreviousView("/bookmark_list.xhtml")
public class BookmarkEditMB extends AbstractEditPageBean<Bookmark, Long> {

    @ExceptionHandler
    public void tratador(ConstraintViolationException cause) {
        messageContext.add("Estou tentando tratar a exceção aqui.", SeverityType.WARN);
    }
}

I have tried to capture all the exception types that occur when deleting, but none of them are captured by the method. I've tried catching other types of exception and it's captured perfectly. In this specific case (deleting) I can not capture it.

On this Demoiselle manual page explain how to use @ExceptionHandler: link

Below is a link to download an example application:

link

Thanks in advance for your help.

    
asked by anonymous 23.03.2015 / 12:56

4 answers

1

Hello. I also go through the same problem. What follows is not a response , it's just the outline solution I've found and I'm using for now. I just got it with the old try-catch ...

No BusinessController:

@Override
public void delete (Long id) {
    try {
        efetivaDelete(id);
    } catch (Exception e) {
        throw new MeuErroException("msg..."); //esse eu consigo pegar no MB
    }
}

@Transactional
private void efetivaDelete(Long id) {
    getDelegate().delete(id);
}

So I was able to get my exception in the @ExceptionHandler from MB.

    
30.06.2015 / 22:39
1

We face the same problem, ConstraintViolationException is encapsulated in TransactionException . So I opted for the following solution:

@ExceptionHandler
public void tratarErroInesperado(RuntimeException e) throws IOException {
    if (tratarConstraintViolationException(e)) {
        return;
    } else {
        ...
    }
}

private boolean tratarConstraintViolationException(Exception e) {
    Throwable cause = e;
    while (cause != null) {
        if (cause instanceof ConstraintViolationException) {
            for (ConstraintViolation<?> violation : cve.getConstraintViolations()) {
                messageContext.add(violation.getMessage(), SeverityType.ERROR);
            }
            return true;
        }
        cause = cause.equals(cause.getCause()) ? null : cause.getCause();
    }
    return false;
}
    
11.10.2016 / 21:49
0

When intercepting exception do the manipulation by type ValidationException , which is the 'parent' exception of that manipulated.

    
28.04.2015 / 19:35
0

Although it is just a kick , I believe the following should work:

@ViewController
@PreviousView("/bookmark_list.xhtml")
public class BookmarkEditMB extends AbstractEditPageBean<Bookmark, Long> {

    @ExceptionHandler
    public void tratador(RollbackException cause) {
        messageContext.add("Estou tentando tratar a exceção RollbackException aqui.", SeverityType.WARN);
        if (cause.getCause() != null) {
            throw cause.getCause();
        }
    }

    @ExceptionHandler
    public void tratador(PersistenceException cause) {
        messageContext.add("Estou tentando tratar a exceção PersistenceException aqui.", SeverityType.WARN);
        if (cause.getCause() != null) {
            throw cause.getCause();
        }
    }

    @ExceptionHandler
    public void tratador(ConstraintViolationException cause) {
        messageContext.add("Estou tentando tratar a exceção ConstraintViolationException aqui.", SeverityType.WARN);
    }
}

My kicks is based on the idea that the ConstraintViolationException exception is probably being thrown out of the scope of the interceptor, whereas the exception RollbackException (and perhaps PersistenceException ) are already within the scope, being possible to be intercepted. Because the exceptions are encapsulated in a string. So, to see them at the desired level, just uncapulate one by one.

    
30.06.2015 / 23:20