Intercept Exception

Asked

Viewed 957 times

7

I am using Demoiselle in my application, but it has not been behaving very well in one aspect. In an association between two or more entities, deleting an exception is made. With the exception treatment available in the Demoiselle, I have devised a method to capture this exception, but we are unable to capture 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 Customer 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 Customer has an association of many to one with Bookmark. Therefore, when registering a customer I should add a Bookmark to it. The problem occurs when deleting a bookmar that has reference in a customer. 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: Cannot delete or update a Parent Row: a Foreign key Constraint fails (db_estacionamento.cliente, CONSTRAINT FK_ht5q4yqv47muisi25vq14yw2u FOREIGN KEY (bookmark_id) REFERENCES bookmark (id))

To try to treat this error, in the Bookmarkeditmb class I created a method to capture this exception. But, specifically this case, it is not possible to 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 kinds of exceptions that occur when deleting, but none of them are captured by the method. I tried to capture other types of exception and she is captured perfectly. In this specific case (when deleting) I cannot capture it.

This page of the Demoiselle manual explains how to use the@ Exceptionhandler: http://demoiselle.sourceforge.net/docs/framework/reference/2.4.2/html/excecao.html#d0e996

Below is a link to download an example application:

https://drive.google.com/file/d/0B2mw7Hlip92vQUhhX2NRWWFrNm8/view?usp=sharing

Thanks for your help.

  • Managed to solve?

  • Hello... Worse than we said today, we still haven’t found a solution!

4 answers

1

We face the same problem, the 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;
}

1

Hello. I also go through the same problem. What follows is not an answer, is just the contour solution I found and am using for now. I only managed with 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 managed to catch my exception on MB @Exceptionhandler.

  • Good morning, it didn’t work! including delete method does not support this Exception.

0

By intercepting the exception do the manipulation by type ValidationException, who is the Exception 'father' of the one who manipulated.

  • 1

    This does not provide an answer to the question. To criticize or request clarification from an author, leave a comment below its publication.

  • Improved, @ramaral ?

  • Now it feels like an answer!

  • thanks, it’s just that I’m new here, I’ve been using it for a long time.

  • Hello. Just to not go unanswered, we also tested it and it didn’t work!

0

Though he’s only one 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);
    }
}

Man kick is based on the idea that probably the exception ConstraintViolationException is being launched outside the scope of the Interceptator, while probably the exception RollbackException (and maybe PersistenceException also) are already within the scope, being possible to be intercepted. As the exceptions are encapsulated in chain. Then, to see them at the desired level, just disembowel one by one.

  • Good morning. I just performed the test, but it doesn’t work! Unfortunately I couldn’t catch the exception!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.