2

I created relation @ManyToMany with the same entity.

Here is my entity:

@Entity
@Table(name = "user")
public class User extends BaseEntity implements Serializable {

...

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "table_friends", joinColumns =
@JoinColumn(name = "userId"), inverseJoinColumns =
@JoinColumn(name = "friendId"))
private List<User> friends;

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "table_friends", joinColumns =
@JoinColumn(name = "friendId"), inverseJoinColumns =
@JoinColumn(name = "userId"))
private List<User> friendsof;

I created a few "users" and added them to friend list:

User u1 = new User();
User u2 = new User();
User u3 = new User();

u1.getFriends().add(u2);
u1.getFriendsof().add(u2);
u1.getFriends().add(u3);
u1.getFriendsof().add(u3);

When I remove a friend from the list u1.getFriends().remove(u3), everything is ok . But when I want to delete the user from the database u3.remove(), friends of u1 still are the same, although already in the database list of friend is correct.

  1. Can I somehow refresh the list after removing a user?
  2. And if so, how can I know which list of friend I need to refresh?

Edit: Also seems to me that I should remove the (cascade = CascadeType.ALL), because when I remove u1, removes all paired members. Is this the correct behavior?

galica
  • 137
  • 1
  • 2
  • 10

2 Answers2

3

Hmm, why do you need 2 list friends and friendsOf? If you're my friend, isn't it obvious that I am your friend?

Besides, if you only want to end the relationship between 2 User, you should use u1.getFriends().remove(u3).

Lastly, if you want to remove a user. You should create an EntityManager em and execute the command em.remove(u3). This command will delete u3 as well as the relationship. However, you should be careful with cascade = CascadeType.ALL. This cascadeType means that if you remove u3, u1 will also be removed. I think you should leave it @ManyToMany without cascade.

Mr.J4mes
  • 9,168
  • 9
  • 48
  • 90
  • All cascade I have already removed. When it comes to remove, I use the EntityManager em.remove(u). But it doesn't work as I expected because after em.remove(u3), when I check in database (by MySQL Administrator), u3 doesn't exist, however it still exist in u1.friends. Disappears after restart program. Any idea why so late? – galica Dec 28 '11 at 11:04
  • hmmm it's weird. I tried to remove an entry in my app and all relationships are updated properly. ^^ I think you should update your question with this weird behavior. I'm sure someone else will be able to help you with it – Mr.J4mes Dec 28 '11 at 11:45
  • I did like what I told you. I called `em.remove('someEntity')`. – Mr.J4mes Dec 28 '11 at 11:55
  • If you invoke `em.refresh(-)`, will it properly reflect new friends list? – Piotr Nowicki Dec 28 '11 at 11:59
  • I can't invoke em.remove or em.refresh directly in the same place where I created Users. User Entity extends BaseEntity which has refresh and remove public method. Maybe that's the problem. After refresh nothing changed :( – galica Dec 28 '11 at 12:06
  • 2
    hmm I think you should not use `EntityManager` inside an `Entity`. Usually, you will inject an `EntityManager` into an Enterprise JavaBean and you will use the bean to persist entities. – Mr.J4mes Dec 28 '11 at 12:19
  • Honestly I never used the EJB. Can I somehow create it quickly or do without it. – galica Dec 28 '11 at 12:32
  • 1
    In my opinon, you should know about EJB. It will help you achieve MVC architecture which is very popular with JavaEE. Take a quick look at the code at the top of this [page](http://openejb.apache.org/examples-trunk/dynamic-datasource-routing/README.html). It's very easy to inject EntityManger into an EJB. – Mr.J4mes Dec 28 '11 at 12:49
  • I checked, and in Netbeans in desktopApplictation I can't create EJB. Of course I can do it manual but I think its not the corrct approach. – galica Dec 28 '11 at 12:50
  • oh your application seems to be a small one. Hmm even so, I think your desktop application still have some class which would listen to request. For example, if the user clicks New, something must be there to wait for that request and act on it. I think you can try injecting the EntityManager into that thing :P – Mr.J4mes Dec 28 '11 at 13:01
0

I found another solution but only when we using EclipseLink.

In persistance.xml you need to add property:

<property name="eclipselink.cache.shared.default" value="false"/>

Then everything works fine.

galica
  • 137
  • 1
  • 2
  • 10