我试图让 ManyToMany 级联事件发挥作用。我浏览类似的帖子,但与其他帖子相比,无法查看我的代码出错的位置。
我有两个表组织和项目,组织是关系的所有者,两者之间有一个关系表。
我正在尝试保留一个新项目实体,该实体可以有一个或多个与之关联的组织。我使用 selectManyListbox (JSF 2)让用户选择多个组织。所有这一切都很好,直到我尝试级联关系。对于与其关联的每个组织,要么只保留项目,要么持久管理器为同一项目创建新副本。即不同的orgID和projID(而不是不同的orgID引用相同的projID)
为什么当我尝试保持关系时,JPA会创建相同项目的新实例(除ID之外的相同属性)?
我正在尝试学习JPA / JSF,非常欢迎任何帮助。问候克里斯。
PS。在Project bean控制器中,我得到了用户选择的正确的组织实例。
具有主键的实体对象
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;
..
}
项目bean控制器
@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);
}
答案 0 :(得分:3)
解决了问题,并将重播发布给可能会犯同样错误的其他人。希望没关系。
问题出在Project bean的 create 函数中。在合并(更新)组织实体之前,我必须先在项目上调用create(persist)。
try {
getFacade().create(current);
for(Organisation org : current.getOrganisationCollection()) {
org.getProjectCollection().add(current);
ejbOrganisationFacade.edit(org);
}
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/resources/Bundle").getString("ProjectCreated"));
return prepareCreate();
} catch (Exception e) {
此外,我在项目外观的 create 方法中出现错误,该方法称为merge而不是persist。这导致了很多问题。很抱歉为这个简单的解决方案占用空间。