Hi, I have I problem and don't even know how to google it. The fact is that I have a Class A than contains a ManyToMany relation with class B and a oneToMany relation with a Class C. When I try to get the class with non-lazy(querying A to have both list) behaviour the number of Rows of B get duplicated each time. If I get two list from separated I seem to work ok. I don't know what's happening:
The source code is as fallows:
package domain;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.CascadeType;
import org.hibernate.annotations.AccessType;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.IndexColumn;
Class A = Template
Class B = Editor
Class C = Resource
@Entity @AccessType("property")
@Table (name="Template")
public class Template implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int id;
private List<Resource> resources;
private List<Editor> editors;
private String MLSname;
private String description;
private HashSet<String> targetUrl;
private Date modifiedDate;
private Administrator administrator;
public Template(){
targetUrl = new HashSet<String>();
resources = new ArrayList<Resource>();
editors = new ArrayList<Editor>();
}
@Id @GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@ManyToMany(
targetEntity=domain.Editor.class,
cascade={CascadeType.MERGE}
)
@JoinTable(
name="TEMPLATE_EDITOR",
joinColumns=@JoinColumn(name="template_id"),
inverseJoinColumns=@JoinColumn(name="editor_id")
)
public List<Editor> getEditors() {
return editors;
}
public void setEditors(List<Editor> editors) {
this.editors = editors;
}
@ManyToOne
@JoinColumn(name="administrator_id")
@Cascade ( { org.hibernate.annotations.CascadeType.SAVE_UPDATE})
public Administrator getAdministrator() {
return administrator;
}
public void setAdministrator(Administrator administrator) {
this.administrator = administrator;
}
@OneToMany
@IndexColumn(name="indexResource")
@JoinColumn(name="template_id")
@Cascade ( { org.hibernate.annotations.CascadeType.ALL,
org.hibernate.annotations.CascadeType.SAVE_UPDATE,
org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
public List<Resource> getResources() {
return resources;
}
public void setResources(List<Resource> resouces) {
this.resources = resouces;
}
public String getMLSname() {
return MLSname;
}
public void setMLSname(String sname) {
MLSname = sname;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public HashSet<String> getTargetUrl() {
return targetUrl;
}
public void setTargetUrl(HashSet<String> targetUrl) {
this.targetUrl = targetUrl;
}
public Date getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(Date modifiedDate) {
this.modifiedDate = modifiedDate;
}
}
package domain;
import java.util.List;
import java.util.ArrayList;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.hibernate.annotations.AccessType;
import org.hibernate.annotations.IndexColumn;
@Entity @AccessType("property")
@Table (name="Editor")
public class Editor extends User {
/**
*
*/
private static final long serialVersionUID = 1L;
public List<Template> templates;
public Editor(){
templates = new ArrayList<Template>();
}
@ManyToMany(
mappedBy = "editors",
cascade={CascadeType.MERGE},
targetEntity = domain.Template.class
)
public List<Template> getTemplates() {
return templates;
}
public void setTemplates(List<Template> templates) {
this.templates = templates;
}
}
package domain;
import java.util.List;
import java.util.ArrayList;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.AccessType;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.IndexColumn;
@Entity @AccessType("property")
@Table (name="Resource")
public class Resource extends RETSClass {
private static final long serialVersionUID = 1L;
private List<Classification> classifications;
private Template template;
public Resource(){
classifications = new ArrayList<Classification>();
}
@ManyToOne
@JoinColumn(name="template_id")
@Cascade ( { org.hibernate.annotations.CascadeType.SAVE_UPDATE})
public Template getTemplate() {
return template;
}
public void setTemplate(Template template) {
this.template = template;
}
@OneToMany
@JoinColumn(name="resource_id")
@IndexColumn(name="indexResource")
@Cascade ( { org.hibernate.annotations.CascadeType.ALL,
org.hibernate.annotations.CascadeType.SAVE_UPDATE,
org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
public List<Classification> getClassifications() {
return classifications;
}
public void setClassifications(List<Classification> classifications) {
this.classifications = classifications;
}
}
and the sql query is this one:
crit.setFetchMode("editors",FetchMode.JOIN); crit.setFetchMode("resources",FetchMode.JOIN);
return (Template)DataAccessUtils.uniqueResult(getHibernateTemplate().findByCriteria(crit));
select this_.id as id7_5_, this_.MLSname as MLSname7_5_, this_.administrator_id as administ6_7_5_, this_.description as descript3_7_5_, this_.modifiedDate as modified4_7_5_, this_.targetUrl as targetUrl7_5_, administra2_.id as id0_0_, administra2_1_.expireDate as expireDate0_0_, administra2_1_.userName as userName0_0_, administra2_1_.userPassword as userPass4_0_0_, editors3_.template_id as template1_7_, editor4_.id as editor2_7_, editor4_.id as id0_1_, editor4_1_.expireDate as expireDate0_1_, editor4_1_.userName as userName0_1_, editor4_1_.userPassword as userPass4_0_1_, resources5_.template_id as template2_8_, resources5_.id as id8_, resources5_.indexResource as indexRes3_8_, resources5_.id as id3_2_, resources5_1_.beSpokeSystemName as beSpokeS2_3_2_, resources5_1_.templateName as template3_3_2_, resources5_.template_id as template2_6_2_, classifica6_.resource_id as resource2_9_, classifica6_.id as id9_, classifica6_.indexResource as indexRes3_9_, classifica6_.id as id3_3_, classifica6_1_.beSpokeSystemName as beSpokeS2_3_3_, classifica6_1_.templateName as template3_3_3_, classifica6_.resource_id as resource2_5_3_, fields7_.classification_id as classifi2_10_, fields7_.id as id10_, fields7_.indexField as indexField10_, fields7_.id as id3_4_, fields7_1_.beSpokeSystemName as beSpokeS2_3_4_, fields7_1_.templateName as template3_3_4_, fields7_.classification_id as classifi2_4_4_ from Template this_ left outer join Administrator administra2_ on this_.administrator_id=administra2_.id left outer join User administra2_1_ on administra2_.id=administra2_1_.id left outer join TEMPLATE_EDITOR editors3_ on this_.id=editors3_.template_id left outer join Editor editor4_ on editors3_.editor_id=editor4_.id left outer join User editor4_1_ on editor4_.id=editor4_1_.id left outer join Resource resources5_ on this_.id=resources5_.template_id left outer join RETSClass resources5_1_ on resources5_.id=resources5_1_.id left outer join Classification classifica6_ on resources5_.id=classifica6_.resource_id left outer join RETSClass classifica6_1_ on classifica6_.id=classifica6_1_.id left outer join Field fields7_ on classifica6_.id=fields7_.classification_id left outer join RETSClass fields7_1_ on fields7_.id=fields7_1_.id where this_.id=?
anyone know what could be happening? any ideas? I defenetly want to get the whole object at once. any help would be really apreciate! I've checked the BD and it looks allright with no duplicated entrys.
thank you again
|