0

In user model class I have the following:

public class User implements Serializable {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;
  @ManyToMany(mappedBy = "attendees", cascade = CascadeType.ALL)
  @Cascade(org.hibernate.annotations.CascadeType.ALL)
  private Set<Timeslot> timeslots = new HashSet<Timeslot>();
}

And I would like to delete the time slots. I've tried something but doesn't work, as follows:

public static boolean deleteUserTimeslot(EntityManager em, Timeslot ts) {
        EntityTransaction transaction = em.getTransaction();
        try {
            ArrayList<User> attendeeList = (ArrayList<User>) ts.getAttendees();

            List<User> attendeesToRemove = (List<User>) getAllUsers(em);
            transaction.begin();

            for(User u: attendeesToRemove){
                for(int i=0;i<attendeeList.size();i++){
                    if(attendeeList.get(i).getId()==u.getId()){

                        em.remove(u.getTimeslots());
                        break;
                    }
                }        
            }
            transaction.commit();


            return true;
        } catch (PersistenceException ex) {
            //Rolling back data transactions
            if (transaction != null && transaction.isActive()) {
                transaction.rollback();
            }
            logger.error("Error making database call for update timeslot status");
            ex.printStackTrace();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            e.printStackTrace();
        }
        return false;
    }

How can I delete the M2M entity?

fvrghl
  • 3,642
  • 5
  • 28
  • 36
  • try `u.getTimeslots().clear(); em.persist(u);`. you have to delete slots from user and persist it, not delete slots directly – Luca Basso Ricci Aug 06 '13 at 19:30
  • thanks, tried that but doesn't seem to work either. – Tarlochan Gill Aug 06 '13 at 19:40
  • I don't think cascading will work. Cascading means that if the `User` is deleted, then its `Timeslot`s will also be deleted. What you want is the `orphanRemoval` flag, which deletes entities which have been removed from a collection. However, that is only available on `@OneToMany`, not `@ManyToMany`. – Tom Anderson Aug 06 '13 at 19:48
  • 1
    Your code here - i'm mostly looking at the bit inside the `try` - is pretty baroque. Are you really looping over all the `User`s in the database and comparing them to each of the `User`s associated with a particular `Timeslot`? Why? What exactly is your end goal here? – Tom Anderson Aug 06 '13 at 19:53
  • the end goal is to get each user in db and checking if that user is assigned to a timeslot, if so, then remove that user's timeslot. but this doesn't work. been trying various ways but to no avail. – Tarlochan Gill Aug 07 '13 at 06:04

1 Answers1

0

Do you really need attendees to be a List instead of a Set? See this.

I two observations when it comes to cascade:

  1. There are to Cascade annotation, remove one of them (or both)
  2. The documentation states that is not recommended to add a Cascade in ManyToMany associations

It does not usually make sense to enable cascade on a or association. Cascade is often useful for and associations.

It seems to me that you want to delete a TimeSlot, right? How about removing the relationship between TimeSlot and User first?

// All attendees with this TimeSlot
ArrayList<User> attendees = (ArrayList<User>) ts.getAttendees();
// Bidirectional association, so let's update both sides of the relationship
// Remove TimeSlot from Attendees
for(User a : attendees){
    a.getTimeslots().remove(ts);
}
// Remove Attendees from TimeSlot
ts.clear();
// Save the changes
em.merge(ts);
em.remove(ts);
Community
  • 1
  • 1
Rafa
  • 1,997
  • 3
  • 21
  • 33
  • thanks but it does not work. in addition there is no such remove method, it gives an error. – Tarlochan Gill Aug 07 '13 at 06:01
  • Please, see my edit for "remove". After doing it is the record still in the JoinTable (possibly named as TimeSlot_User)? – Rafa Aug 07 '13 at 12:24