entityManager merge instance throws java.lang.UnsupportedOperationException
talsitt Jan 18, 2009 1:58 PMI'm using seam 2.0 for my application
I got an exception java.lang.UnsupportedOperationException when i try to merge the instance,
I tried the following Scenarios
- Persist the object without setting the categories (ManyToMany Relation) : The object can be persisted and updated
- Persist the Object with setting the Categories : The object will be persisted but if i tried to merge it will throw (java.lang.UnsupportedOperationException)
Hope if anyone could give me a hint
Here is the code
@Name("standard") @Entity @Table(name = "gso_standard") public class Standard { // This is the Category relation that i believe it caused the exception @ManyToMany @JoinTable(name = "STD_CAT", joinColumns = @JoinColumn(name = "STD_ID"), inverseJoinColumns = @JoinColumn(name = "CAT_ID")) private List<Category> stdCategroies = new ArrayList(); @ManyToMany(cascade = CascadeType.REFRESH) @JoinTable(name = "STD_REPLACEMENT", joinColumns = @JoinColumn(name = "REPLACED_STD_ID"), inverseJoinColumns = @JoinColumn(name = "OLD_STD_ID")) private List<Standard> replacersStandards; @ManyToMany(mappedBy = "replacersStandards",cascade = CascadeType.REFRESH) private List<Standard> replacedStandards; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "UPDATED_STD_ID") private Standard oldUpdatedStandard; @Id @GeneratedValue private Long id; private String fullName; @NotNull private String prefix; @NotNull private String no; private String partNo; private String sectionNo; @NotNull @Length(min = 4, max = 4) private String issueDate; private String refPrefix; private String refNo; private String refPartNo; private String refSectionNo; private String refIssueDate; private String oldNo; private String titleAr; @NotNull private String titleEn; @Lob private String scopeAr; @Lob private String scopeEn; @NotNull private String ics1; private String ics2; private String ics3; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "type_id", referencedColumnName = "id") private Type type; private String assignedTo; @OneToMany(cascade = CascadeType.ALL) private List<LanguagePages> langPages = new ArrayList(); @ManyToOne private TechnicalCouncil techCouncil; @ManyToOne private BoardOfDirectors bod; @ManyToOne private TechnicalCommittee techCommittee; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "state_ID", referencedColumnName = "id") private State state; private Boolean cancelled; @Basic @Temporal(TemporalType.DATE) private Date cancelDate; private String note; private Boolean suspended; @Column(name = "doc_en") private String docEn; @Column(name = "doc_ar") private String docAr; @Column(name = "doc_update_ar") private String docUpdateAr; @Column(name = "doc_updatE_en") private String docUpdateEn; private String updateBy; @NotNull @Basic @Temporal(TemporalType.TIMESTAMP) private Date updateDate; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getFullName() { return fullName; } public void setFullName(String fullName) { this.fullName = fullName; } public String getPrefix() { return prefix; } public void setPrefix(String prefix) { this.prefix = prefix; } public String getRefPrefix() { return refPrefix; } public void setRefPrefix(String refPrefix) { this.refPrefix = refPrefix; } public String getRefNo() { return refNo; } public void setRefNo(String refNo) { this.refNo = refNo; } public String getRefPartNo() { return refPartNo; } public void setRefPartNo(String refPartNo) { this.refPartNo = refPartNo; } public void setOldNo(String oldNo) { this.oldNo = oldNo; } public String getTitleAr() { return titleAr; } public void setTitleAr(String titleAr) { this.titleAr = titleAr; } public String getTitleEn() { return titleEn; } public void setTitleEn(String titleEn) { this.titleEn = titleEn; } public String getScopeAr() { return scopeAr; } public void setScopeAr(String scopeAr) { this.scopeAr = scopeAr; } public String getScopeEn() { return scopeEn; } public void setScopeEn(String scopeEn) { this.scopeEn = scopeEn; } public String getAssignedTo() { return assignedTo; } public void setAssignedTo(String assignedTo) { this.assignedTo = assignedTo; } public Boolean getCancelled() { return cancelled; } public void setCancelled(Boolean cancelled) { this.cancelled = cancelled; } public Date getCancelDate() { return cancelDate; } public void setCancelDate(Date cancelDate) { this.cancelDate = cancelDate; } public String getNote() { return note; } public void setNote(String note) { this.note = note; } public String getIssueDate() { return issueDate; } public void setIssueDate(String issueDate) { this.issueDate = issueDate; } public String getRefIssueDate() { return refIssueDate; } public void setRefIssueDate(String refIssueDate) { this.refIssueDate = refIssueDate; } public State getState() { return state; } public void setState(State state) { this.state = state; } public String getUpdateBy() { return updateBy; } public void setUpdateBy(String updateBy) { this.updateBy = updateBy; } public Date getUpdateDate() { return updateDate; } public void setUpdateDate(Date updateDate) { this.updateDate = updateDate; } public String getIcs1() { return ics1; } public void setIcs1(String ics1) { this.ics1 = ics1; } public String getIcs2() { return ics2; } public void setIcs2(String ics2) { this.ics2 = ics2; } public String getIcs3() { return ics3; } public void setIcs3(String ics3) { this.ics3 = ics3; } public String getNo() { return no; } public void setNo(String no) { this.no = no; } public String getSectionNo() { return sectionNo; } public void setSectionNo(String sectionNo) { this.sectionNo = sectionNo; } public String getDocEn() { return docEn; } public void setDocEn(String docEn) { this.docEn = docEn; } public String getDocAr() { return docAr; } public void setDocAr(String docAr) { this.docAr = docAr; } public String getDocUpdateAr() { return docUpdateAr; } public void setDocUpdateAr(String docUpdateAr) { this.docUpdateAr = docUpdateAr; } public String getDocUpdateEn() { return docUpdateEn; } public void setDocUpdateEn(String docUpdateEn) { this.docUpdateEn = docUpdateEn; } public String getPartNo() { return partNo; } public void setPartNo(String partNo) { this.partNo = partNo; } public String getRefSectionNo() { return refSectionNo; } public void setRefSectionNo(String refSectionNo) { this.refSectionNo = refSectionNo; } public String getOldNo() { return oldNo; } public Type getType() { return type; } public void setType(Type type) { this.type = type; } public TechnicalCouncil getTechCouncil() { return techCouncil; } public void setTechCouncil(TechnicalCouncil techCouncil) { this.techCouncil = techCouncil; } public BoardOfDirectors getBod() { return bod; } public void setBod(BoardOfDirectors bod) { this.bod = bod; } public TechnicalCommittee getTechCommittee() { return techCommittee; } public void setTechCommittee(TechnicalCommittee techCommittee) { this.techCommittee = techCommittee; } public List getLangPages() { return langPages; } public Boolean getSuspended() { return suspended; } public void setSuspended(Boolean suspended) { this.suspended = suspended; } public List<Category> getStdCategroies() { return stdCategroies; } public void setStdCategroies(List<Category> stdCategroies) { this.stdCategroies = stdCategroies; } public void setLangPages(List<LanguagePages> langPages) { this.langPages = langPages; } public List<Standard> getReplacedStandards() { return replacedStandards; } public void setReplacedStandards(List<Standard> replacedStandards) { this.replacedStandards = replacedStandards; } public Standard getOldUpdatedStandard() { return oldUpdatedStandard; } public void setOldUpdatedStandard(Standard oldUpdatedStandard) { this.oldUpdatedStandard = oldUpdatedStandard; } public List<Standard> getReplacersStandards() { return replacersStandards; } public void setReplacersStandards(List<Standard> replacersStandards) { this.replacersStandards = replacersStandards; } public String getComposedName() { StringBuffer result = new StringBuffer(); result.append(prefix); result.append(" " + no); result.append(partNo == null || partNo.equals("") ? "" : "-" + partNo); result.append(sectionNo == null || sectionNo.equals("") ? "" : "-" + sectionNo); result.append(":" + issueDate); return result.toString(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Standard other = (Standard) obj; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; return true; } }
And below is the Category Entity
@Entity @Table(name = "project_category") @Name("category") public class Category implements Serializable { @Id @GeneratedValue private Long id; @Column(name = "name_ar") private String nameAr; @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Category other = (Category) obj; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; return true; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getNameAr() { return nameAr; } public void setNameAr(String nameAr) { this.nameAr = nameAr; } }
The Second Class is the Bussiness class that manages the actions
@Name("standardHome") @Scope(ScopeType.CONVERSATION) public class StandardHome { @Out(required = false) private List<Standard> replacerStandards; @In(create = true) private EntityManager entityManager; @DataModel("standards") private List standards; @DataModelSelection @In(required = false, create = true) @Out(required = false) private Standard standard; @Factory("standards") @Begin(join = true) public void listStandards() { //code that fetches all the standards } public String saveStandard() { standard.setUpdateBy(loggedUser.getUsername().toLowerCase()); standard.setUpdateDate(new Date(System.currentTimeMillis())); standard.setFullName(standard.getComposedName()); entityManager.persist(standard); return "persisted"; } public String updateStandard() { standard.setUpdateBy(loggedUser.getUsername().toLowerCase()); standard.setUpdateDate(new Date(System.currentTimeMillis())); standard.setFullName(standard.getComposedName()); entityManager.merge(standard); return "updated"; }
Finally here is the code fragment that manage the category selection
<s:decorate id="stdCategoryDecor" template="layout/edit.xhtml"> <ui:define name="label">#{messages['std.sector']}</ui:define> <h:selectManyCheckbox id="groups" value="#{standard.stdCategroies}" layout="pageDirection" rendered="#{standard.stdCategroies != null}" > <s:selectItems value="#{lookup.categories}" var="cat" label="#{cat.nameAr}"/> <s:convertEntity/> </h:selectManyCheckbox> </s:decorate> <div class="actionButtons"> <h:commandButton id="persist" value="#{messages['std.create.standard']}" action="#{standardHome.saveStandard}" rendered="#{standard.id == null}" /> <h:commandButton id="update" value="#{messages['std.update.standard']}" action="#{standardHome.updateStandard}" rendered="#{standard.id != null}" /> <s:button id="cancel" value="#{messages['std.cancel']}" propagation="end" view="/listStandards.xhtml" /> </div>