我在尝试进行ManyToMany级联事件时遇到了麻烦.我已经浏览了类似的文章,但是与其他文章相比,我的代码哪里出错了.
我有两个表Organization和Project,Organization是关系的所有者,并且两者之间有一个关系表.
我试图保留一个新的项目实体,该实体可以具有一个或多个与其关联的组织.我使用selectManyListbox(JSF 2)让用户选择多个组织.在我尝试级联关系之前,所有这些工作都很好.对于与项目关联的每个组织,要么只是持久化项目,要么是持久化经理创建同一项目的新副本.即不同的orgID和projID(而不是不同的orgID引用相同的projID)
当我尝试保持关系时,为什么JPA会创建同一Project的新实例(相同的属性,除了ID)?
我正在尝试学习JPA / JSF,非常感谢您的帮助.问候克里斯.
PS.在Project bean控制器中,我获得了用户选择的正确的Organization实例.
具有主键的实体对象
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);
}
解决方法:
解决了问题,然后将重播发布给可能会犯与我相同的错误的其他人.希望没事.
问题出在Project bean的create函数中.在合并(更新)组织实体之前,我必须先在项目上调用创建(持久).
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.这会导致很多问题.很抱歉占用如此微不足道的解决方案的空间.