Hi all,
I really don't understand this. I changed the code so the save operation happens outside the loop generating the tree structure. This leads to a more structure record structure in the database but still I get double entries.
My test results have been like this:
* Individual save operation on CategoryLookup and Category inside the loop: quadruple entries on all tables
* Move Category save outside of initial loop: double entries on categories quadruple entries on CategoryLookup
* Move CategoryLookup outside of initial loop: correct entries on categories and
double entries on CategoryLookup
The point is
1. I don't see the difference between any of the cases above. They should all yield the same result
2. I don't see why there are double entries on CategoryLookup. The list contains a single and correct set of entries. Why is it saved twice?
The fact that moving the CategoryLookup outside of the loop influences the number of entries on the categories table is also weird, since there's only a manyToOne relation from Category=>CategoryLookup but not the other way around.
Any ideas?
Kind regards,
Marc
Code:
Category
@ManyToOne(cascade=CascadeType.MERGE)
@JoinColumn(name="FK_ParentID",nullable=true)
public Category getParent() {
return parent;
}
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
public Set<Category> getChildren() {
return children;
}
public void addChild(Category category){
if(children == null)
children = new HashSet<Category>();
children.add(category);
}
@ManyToOne(cascade=CascadeType.MERGE)
@JoinColumn(name="FK_CategoryLookupID",nullable=false)
public CategoryLookup getCatLookup() {
return catLookup;
}
public int hashCode() {
return new HashCodeBuilder(765233521, 1856390359).appendSuper(
super.hashCode()).append(this.category).append(this.views)
.append(this.hidden).append(this.isPremium).append(this.catLookup).append(this.parent).append(this.country)
.toHashCode();
}
public boolean equals(Object object) {
if (!(object instanceof Category)) {
return false;
}
Category rhs = (Category) object;
return new EqualsBuilder().append(
this.category, rhs.category).append(this.views, rhs.views)
.append(this.hidden, rhs.hidden).append(this.isPremium,
rhs.isPremium).append(this.categoryId, rhs.categoryId)
.append(this.catLookup, rhs.catLookup).append(this.children,
rhs.children).append(this.parent, rhs.parent).append(
this.country, rhs.country).isEquals();
}
CategoryLookup
public int hashCode() {
return new HashCodeBuilder(-1431736281, -818998207).append(this.categoryName).append(this.Id)
.toHashCode();
}
/**
* @see java.lang.Object#equals(Object)
*/
public boolean equals(Object object) {
if(this == object)return true;
if (!(object instanceof CategoryLookup)) {
return false;
}
CategoryLookup rhs = (CategoryLookup) object;
return new EqualsBuilder().append(
this.categoryName, rhs.categoryName).append(this.Id, rhs.Id)
.isEquals();
}
Code:
CategoryManager
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
Category prevCat = null;
int previous = 0;
List<Category> rootCats=new ArrayList<Category>();
List<CategoryLookup> lookups =new ArrayList<CategoryLookup>();
try {
while ((line = br.readLine()) != null) {
if(line.indexOf('=') == -1)
//Reached end of file
break;
String[] ra = line.split("=");
CategoryLookup cl = new CategoryLookup();
Category cat = new Category();
cat.setCatLookup(cl);
cat.setCountry(targetCountry);
if (log.isDebugEnabled())
log.debug(line);
if (line.charAt(0) == '\t' && line.charAt(1) == '\t') {
// level 2
if (log.isDebugEnabled())
log.debug("level 2");
if (previous == 2) {
// parent is same category parent
cat.setParent(prevCat.getParent());
prevCat.getParent().addChild(cat);
} else {
// previous = 1
cat.setParent(prevCat);
prevCat.addChild(cat);
}
if (ra.length > 1) {
cat.setCategory(ra[1].trim());
} else {
cat.setCategory(ra[0].trim());
}
previous = 2;
} else if (line.charAt(0) == '\t') {
// level 1
if (log.isDebugEnabled())
log.debug("level 1");
if (previous == 2) {
// parent is previos category parent.parent
cat.setParent(prevCat.getParent().getParent());
prevCat.getParent().getParent().addChild(cat);
} else if (previous == 1) {
// parent is the same
cat.setParent(prevCat.getParent());
prevCat.getParent().addChild(cat);
} else {
// parent is root
cat.setParent(prevCat);
prevCat.addChild(cat);
}
if (ra.length > 1) {
cat.setCategory(ra[1].trim());
} else {
cat.setCategory(ra[0].trim());
}
previous = 1;
} else {
// level 0
rootCats.add(cat);
if (log.isDebugEnabled())
log.debug("level 0");
if (ra.length > 1) {
cat.setCategory(ra[1]);
} else {
cat.setCategory(ra[0]);
}
previous = 0;
}
CategoryLookup clTmp=null;
for(CategoryLookup cl2 : lookups){
if(cl2.getCategoryName().equals(ra[0])){
clTmp = cl2;
break;
}
}
if(clTmp != null){
// the lookup already exists. Use existing one
cl = clTmp;
cat.setCatLookup(cl);
}else{
cl.setCategoryName(ra[0].trim());
}
prevCat = cat;
lookups.add(cl);
// cl = catLookupDao.save(cl);
// cat = categoryDao.save(cat);
}
br.close();
for (CategoryLookup cl : lookups){
catLookupDao.save(cl);
}
catLookupDao.flush();
for(Category myCat : rootCats){
categoryDao.save(myCat);
}
} catch (IOException io) {
log.error(io);
}