Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing JPA, what's the correct way to delete a record only if it does not have any references to it?
    text
    copied!<p>Say we have an old Book and Authors model, with CRUDs for both. When the user tries to delete an Author, I want to tell her if the author already has books registered, that she must delete the author's books first.</p> <p>Namely, I want to delete a record only if it has not any references to it, but if it does, I just want to warn the user.</p> <p><strong>1st approach:</strong></p> <p>The way I've been doing until now looks like this:</p> <pre><code>@PersistenceContext private EntityManager em; public void deleteAuthor(Author author){ Long qtBooks = em.createQuery( "SELECT COUNT(b) FROM Book b WHERE b.author.id = :id") .setParameter("id", author.getId()).getSingleResult(); if (qtBooks &gt; 0) { throw IllegalArgumentException("This author has books registered"); } em.remove(em.getReference(Author.class, author.getId())); } </code></pre> <p>... and in the presentation layer (a JSF bean) I catch the exception, an <code>IllegalArgumentException</code> in this case, and show its error message to the user.</p> <p><strong>2nd approach:</strong></p> <p>As I'm using Spring, I know that another way of doing it would be catching Spring's <code>DataIntegrityViolationException</code>, in the presentation layer. Then, the business method would just have the code to remove the entity:</p> <pre><code>public void deleteAuthor(Author author){ em.remove(em.getReference(Author.class, author.getId())); } </code></pre> <p>... and then the presentation layer (a JSF bean, in my case) can just catch the Spring Exception:</p> <pre><code>@ManagedProperty("#{authorService}"); private AuthorService authorService; public void deleteAuthor(Author author) { try { authorService.deleteAuthor(author); addGlobalInfo("Author deleted"); } catch (DataIntegrityViolationException e) { addGlobalError("This author already has books associated"); } redirect(getRequestURL()); } </code></pre> <p>Now, I've been doing the 1st approach for some time, and I'm finding this second approach much easier to write. My question is, besides of making my application more tied to Spring using this specific Exception, what are the drawbacks of doing the second approach? What are the real pros of the 1st one? Is it good, anyway? Is there a third, better approach for doing this with JPA?</p> <p>As both approaches rely on catching some exception (except the first one throws before trying to change anything in the database), I don't really know how to decide.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload