Reputation: 1256
@Entity
public class Perosn implements Serializable {
....
private Collection<Team> teams;
....
@ManyToMany(fetch = FetchType.LAZY)
@Cascade({CascadeType.ALL})
@JoinTable(name = "person_team",
joinColumns = { @JoinColumn(name = "person_id")},
inverseJoinColumns = {@JoinColumn(name = "team_id")})
public Collection<Team> getTeams() {
return advisers;
}
}
@Entity
public class Team implements Serializable {
....
private Collection<Person> persons;
....
@ManyToMany(fetch = FetchType.LAZY)
@Cascade({CascadeType.ALL})
@JoinTable(name = "person_team",
joinColumns = { @JoinColumn(name = "team_id")},
inverseJoinColumns = {@JoinColumn(name = "person_id")})
public Collection<Person> getPersons() {
return advisers;
}
}
@Service("teamService")
public class TeamService extends DataAccess {
....
public void addTeamToPerson(String teamId, String personId) {
Team team= getTeam(teamId);
Person person= personService.getPerson(personId);
person.getTeams().add(team);
super.update(team);
}
....
}
public abstract class DataAccess<E> {
private EntityManager manager;
....
public void update(E object) {
try {
manager.getTransaction().begin();
manager.merge(object);
manager.getTransaction().commit();
} catch (Exception e) {
....
}
}
....
}
This structure works truly but I think it's strange adding an team object to team collection of person object and updating the team object. Is it wrong logically? I need to know there is a master-slave feature or something like that in this type of relation.
Any guide will be regarded.
Upvotes: 0
Views: 195
Reputation: 692151
Your mapping is wrong: instead of defining a many-to-many bidirectional association, you're defining two many-to-many unidirectional associations, using the same join table.
A bidirectional association always has an owner side and an inverse side. The owner side is the one without the mappedBy
attribute. The inverse side must have a mappedBy
attribute. Think about it: why would you need to tell Hibernate twice how a bidirectional association is mapped?
The mapping should be:
@Entity
public class Person implements Serializable {
....
private Collection<Team> teams;
....
@ManyToMany(fetch = FetchType.LAZY)
@Cascade({CascadeType.ALL})
@JoinTable(name = "person_team",
joinColumns = { @JoinColumn(name = "person_id")},
inverseJoinColumns = {@JoinColumn(name = "team_id")})
public Collection<Team> getTeams() {
return advisers;
}
}
@Entity
public class Team implements Serializable {
....
private Collection<Person> persons;
....
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "teams")
@Cascade({CascadeType.ALL})
public Collection<Person> getPersons() {
return advisers;
}
}
In this case, the owner side is Person
. This means that to add an association between a person and a team, you need to add the team to the teams collection of the person. You may choose to map it the other way, and in this case, you'll need to add the person to the team collection of persons.
Also, note that having CascadeType.ALL
on a ManyToMany association is really dubious: do you really want to delete all the persons when you delete a team, and to delete all the teams of the deleted persons, etc.?
Upvotes: 1