-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Theorical problem (entity being persisted twice)
PostPosted: Mon Dec 07, 2009 10:18 am 
Newbie

Joined: Tue Jun 23, 2009 7:59 am
Posts: 6
Hi!

I'm confused and I think I'm missing some concept.

The sort version: The entity is persisted twice if I call childEntityDAO.makePersistent(e).

The long version: I have 2 entities, Company and Division.

Code:
package com.eukleia.model.entity.common;

import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.Cascade;
import org.jboss.seam.annotations.Name;

@Entity
@Table(name="COMPANY")
@EntityListeners(com.eukleia.model.entity.common.monitor.CompanyMonitor.class)
@Name("company")
public class Company implements Serializable {
   private static final long serialVersionUID = -7076265969258176592L;
   
   @Id @GeneratedValue
   @Column(name="COMPANY_ID")
   private Long id;
   
   @Column(name="COMPANY_NAME")
   private String name;
   
   @Column(name="COMPANY_FOLDER")
   private String folder;
   
   @Column(name="COMPANY_TRIAL")
   private boolean trial;
   
   @Temporal(TemporalType.DATE)
   @Column(name="COMPANY_EXPIRES")
   private Date expires;
   
   @OneToMany(mappedBy = "company", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
   @Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
   private Set<Division> divisions = new HashSet<Division>();
   
   public Company() {}

   public Company(String name){
      this.name = name;
   }
   
       // getters and setters

   public void addDivision(Division division) {
      division.setCompany(this);
      divisions.add(division);
   }
   
   public boolean hasExpired() {
      if (this.expires == null)
         return false;
      
      if (this.expires.before(new Date()))
         return true;
      
      return false;
   }
   
   @Override
   public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + ((folder == null) ? 0 : folder.hashCode());
      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;
      Company other = (Company) obj;
      if (folder == null) {
         if (other.folder != null)
            return false;
      } else if (!folder.equals(other.folder))
         return false;
      if (id == null) {
         if (other.id != null)
            return false;
      } else if (!id.equals(other.id))
         return false;
      return true;
   }
}


Code:
package com.eukleia.model.entity.common;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.jboss.seam.annotations.Name;

@Entity
@EntityListeners(com.eukleia.model.entity.common.monitor.DivisionMonitor.class)
@Table(name="DIVISION")
@Name("division")
public class Division implements Serializable{
   private static final long serialVersionUID = 4771732014913737248L;
   
   @Id @GeneratedValue
   @Column(name="DIVISION_ID")
   private Long id;
   
   @Column(name="DIVISION_NAME")
   private String name;
   
   @Column(name="DIVISION_FOLDER")
   private String folder;
   
   @Column(name="DIVISION_USERNAME")
   private String username;
   
   @Column(name="DIVISION_PASSWORD")
   private String password;   
   
   @ManyToOne(targetEntity = com.eukleia.model.entity.common.Company.class)
   @JoinColumn(name = "COMPANY_ID", nullable = false)
   private Company company;
   
   @OneToMany(mappedBy = "division", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
   @Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
   private Set<User> users = new HashSet<User>();
   
   @OneToMany(mappedBy = "division", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
   @Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
   private Set<Course> courses = new HashSet<Course>();
   
   public Division() {}
   
   public Division(String name) {
      this.name = name;
   }
   
   public Division(String name, Company company) {
      this.name = name;
      this.company = company;
   }
   
   public Division(String name, String folder, String username,
         String password, Company company) {

      this.name = name;
      this.folder = folder;
      this.username = username;
      this.password = password;
      this.company = company;
   }

   public Division(String name, String folder, String username, String password) {
      super();
      this.name = name;
      this.folder = folder;
      this.username = username;
      this.password = password;
   }

        // getters and setters

   public void addUser(User user) {
      user.setDivision(this);
      users.add(user);
   }
   
   public void addCourse(Course course) {
      course.setDivision(this);
      courses.add(course);
   }
   
   @Override
   public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + ((folder == null) ? 0 : folder.hashCode());
      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;
      Division other = (Division) obj;
      if (folder == null) {
         if (other.folder != null)
            return false;
      } else if (!folder.equals(other.folder))
         return false;
      if (id == null) {
         if (other.id != null)
            return false;
      } else if (!id.equals(other.id))
         return false;
      return true;
   }
}


The DAO layers is implemented as described in the section 16.4.2 of Java Persistence with Hibernate. If I try to save a Division like the follow listing it works fine:

Code:
Company c = companyDAO.findById(new Long(2), true);
Division d = new Division("Division 999", "Division 999", "division.999", "password");
c.addDivision(d);
c = companyDAO.makePersistent(c);


But if I call the divisionDAO.makePersistent(d) I got 2 identical (apart form the ID column) rows on my database. I need to call the makePersistent method because I need to get the ID of the persisted entity to use on my tests.

I suppose it is something related with the mapping strategy, but I can't figure it out by myself.

Any ideas appreciated,


Top
 Profile  
 
 Post subject: Re: Theorical problem (entity being persisted twice)
PostPosted: Tue Dec 08, 2009 6:42 am 
Newbie

Joined: Tue Jun 23, 2009 7:59 am
Posts: 6
I found out that there is a bug (http://opensource.atlassian.com/projects/hibernate/browse/HHH-3810) that affects the version of the hibernate I was using.

I updated to the 3.3.2 but it didn't stop the entity to be persisted twice.

As far as I understood from the book if I call:
Code:
Company c = companyDAO.findById(new Long(2), true);
Division d = new Division("Division 999", "Division 999", "division.999", "password");
c.addDivision(d);
c = companyDAO.makePersistent(c);
d = divisionDAO.makePersistent(d);


The d = divisionDAO.makePersistent(d) should be ignored. There must be something wrong with my mapping then.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.