Я застрял, пытаясь заставить работать ManyToMany каскадное событие.Я просматривал похожие посты, но не вижу, где мой код работает неправильно, по сравнению с другими постами.
У меня есть две таблицы Организация и Проект Организация является владельцем отношений, и между ними существует таблица отношений.
Я пытаюсь сохранить новый объект проекта, с которым может быть связана одна или несколько организаций.Я использую selectManyListbox (JSF 2), чтобы позволить пользователю выбрать более одной организации.Все это прекрасно работает, пока я не попытаюсь каскадно связать отношения.Либо только проект становится постоянным, либо постоянный менеджер создает новые копии одного и того же проекта для каждой связанной с ним организации.Т.е. разные orgID и projID (вместо разных orgID ссылаются на один и тот же projID)
Почему JPA создает новый экземпляр того же самого Project (идентичные свойства, кроме идентификатора), когда я пытаюсь сохранить отношение?
Я пытаюсь выучить JPA / JSF, и любая помощь очень приветствуется.Привет Крис.
PS.В контроллере компонента Project я получил нужные экземпляры организаций, которые выбирает пользователь.
Объекты сущностей с первичными ключами
public class Organisation implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "idOrganisation")
private Integer idOrganisation;
..
@JoinTable(name = "organisationproject", joinColumns = {
@JoinColumn(name = "fkOrganisation", referencedColumnName = "idOrganisation")}, inverseJoinColumns = {
@JoinColumn(name = "fkProject", referencedColumnName = "idProject")})
@ManyToMany (fetch=FetchType.EAGER, cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
private Collection<Project> projectCollection;
..
}
public class Project implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "idProject")
private Integer idProject;
..
@ManyToMany(mappedBy = "projectCollection")
private Collection<Organisation> organisationCollection;
..
}
Контроллер компонента проекта
@ManagedBean (name="projectController")
@SessionScoped
public class ProjectController implements Serializable {
private Project current;
private UISelectMany selectedOrganisations;
...
public String create() {
UserController userBean = JsfUtil.findBean("userController", UserController.class);
current.setUser(userBean.getSessionUser());
current.setTimeStamp(JsfUtil.getTimeStamp());
try {
//Use the OrganisationFacade, who is the owner of the relationship and uses Cascade to update the relation
for(Organisation org : current.getOrganisationCollection()) {
org.getProjectCollection().add(current);
ejbOrganisationFacade.edit(org);
}
//getFacade().create(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/resources/Bundle").getString("ProjectCreated"));
return prepareCreate();
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/resources/Bundle").getString("PersistenceErrorOccured"));
return null;
}
}
public UISelectMany getSelectedOrganisations() {
return selectedOrganisations;
}
public void setSelectedOrganisations(UISelectMany selectedOrganisations) {
this.selectedOrganisations = selectedOrganisations;
}
...
}
Наконец, функция редактирования фасада Organiasation
@Override
public void edit(Organisation entity) {
getEntityManager().merge(entity);
}