Remove association in relation to Many to Many

Asked

Viewed 1,101 times

4

I have a relationship @manytomany unidirectional and need to remove this association according to some criteria but did not want to have to browse through all objects in the collection to remove one-by-one.

I thought of a JQPL "delete from ..." but I don’t know how to do it.

Obs:

  • None of the objects will be excluded, only the association between them.
  • Working with Multitenant with multiple Databases, where each client has its own database.

2 answers

2

To delete only the association is simple. Suppose the scenario below:

@ManyToMany(cascade = CascadeType.PERSIST) 
private List<Foo> foos;

If you remove an element from Foos and save the entity you will delete the record in the Join table.

EDIT

I don’t particularly like to run away from the ORM context. So if going through the list and deleting the elements one by one is a burden I can give two alternatives:

  1. If you can use java 8, use a Lamda. With a single command you scroll through the list and remove what you want.
  2. If Java 8 is not a solution, use the utluiz answer. It serves you.

As I told you in the comments: This type of approach you seek is not cool because it creates the need to perform a delete and then a refresh to update your entire session (which will ultimately be less performatic), and make your system error-prone as you are dealing with objects detached who may accidentally be rearward, making your system inconsistent.

Go through the list, delete the elements and then save the object is less costly in most cases as you are working in-memory most of the time, and more robust by not leaving the ORM context.

So if you’re going to work in a different way than this I suggest you evaluate if JDBC won’t suit you better.

  • The problem is that I won’t delete any of the two objects, I just want to unlink them.

  • @Nilsonuehara edited my answer, see if it helps.

  • Yes, that’s what I do now. I wanted to avoid having to iterate all collections to remove one by one. I wanted to do something like: delete from Link Where B.id=1, so all objects that are related to B would have their link deleted.

  • @Nilsonuehara you have to understand that this is not SQL. Using this type of approach can make your Entity manager confused and cause inconsistencies, if it is to work that way I suggest you use jdbc. Now the answer of utluiz does what you want.

  • Edgar, your answer is the correct answer from JPA’s point of view. The problem is that this solution is sub-optimal, because JPA is sub-optimal for this type of task. In fact, all these problems have made me think 500 times before using JPA on a project. Jdbctemplate has given me much less headache in projects that have moderate level of complexity at least.

  • @utluiz I agree in part with you. There is no silver bullet, that’s fact. Now a lot of people use technology in ways that shouldn’t be used, it creates thoughts like what you’ve expressed, which in a way is fair. What user wants with this question is to ask a by-pass in the framework, which should not be done. There is a saying that says: Being able to do something doesn’t mean you should do it.

Show 1 more comment

0


It is possible to execute a delete or even update by means of the JPQL method createQuery of EntityManager.

Example (source):

Query query = em.createQuery(
    "DELETE FROM EntidadeAssociacao t WHERE t.idOrigem = :idOrigem and t.idDestino = :idDestino");
int deletedCount = query
    .setParameter("idOrigem", 1)
    .setParameter("idDestino", 2)
    .executeUpdate();

However, it is important to remember that any command of this nature or via Native query (native query) directly affects the base, so entities in the JPA context may not reflect the change immediately.

If necessary, use the method entityManager.refresh() to update entities.

  • In the case "Association table" is the name of the table in the database? Because I work with Multitenant with multiple Databases (each client has its own database).

  • 1

    @utluiz your answer works, but it is necessary to be careful with the entities that will be detached session.

  • @Nilsonuehara Actually, there goes the class name. Bad example. Sorry :S

  • @Edgarmunizberlinck Yes, taking care not to reuse objects that have been removed from the database is the least care the developer needs to have.

  • Perai @utluiz, let me get this straight... for your tip to work I should create a new class/entity that will represent the association table? That way I think it solves my problem.

  • @Nilsonuehara Yes, in the example I need to have a class. But even if you don’t have you can use the method createNativeQuery to directly access the table. Sorry I haven’t explained more in detail, but it’s kind of hard this week.

  • @utluiz How do I delete the association without it being mapped?

  • @Diegoaugusto If it is only one item you can delete at one end, that is, in one of the entities where the relationship is mapped. Or, as I mentioned above, use a native query.

  • @utluiz I tried the method you mentioned, but I have an error saying that my entity is not mapped. I wanted to delete only the item from the relationship and keep the other tips

  • @Diegoaugusto Impossible to help like this. Create a new question is to put the details of your classes.

  • @utluiz http://answall.com/questions/134183/excluir-entidade-criada-de-uma-rela%C3%A7%C3%A3o-manytomany

Show 6 more comments

Browser other questions tagged

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