title: A different object with the same identifier value was already associated with the session:. neither merge nor saveOrUpdate works
body: <p>I have a GUI where a list of teachers is shown. Two are selected by the user - they are going to be the form teachers of a new school class that gets created.
  The teacher - class relationship is n-m.</p>
  
  <p>School class: (it inherits its id from its group)</p>
  
  <pre><code>@Entity
  @Table(name="school_classes")
  @Cacheable(true)
  public class SchoolClass extends Group{
  
      @ManyToMany(cascade=CascadeType.ALL, mappedBy="classes", fetch=FetchType.EAGER)
      private SortedSet&lt;Teacher&gt; teachers;
  </code></pre>
  
  <p>Teacher:</p>
  
  <pre><code>  @Entity
      @Table(name="teachers")
      @Cacheable(true)
      public class Teacher extends creator.models.school.Entity{
              // name etc
  
      @ManyToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
      @JoinTable(name="class_teachers",
      joinColumns = @JoinColumn(name="teacher_id", referencedColumnName="id"),
      inverseJoinColumns = @JoinColumn(name="class_id", referencedColumnName="id"))
      private SortedSet&lt;SchoolClass&gt; classes;
  </code></pre>
  
  <p>I try to create a new class like this:</p>
  
  <pre><code>String className = request.getParameter("class_name");
  String id1 = request.getParameter("class_teacher1");
  String id2  = request.getParameter("class_teacher2");
  Teacher t1 = DataRetrieveModule.getTeacher(id1);
  Teacher t2 = DataRetrieveModule.getTeacher(id2);
  
  
  Layout l = new Layout();
  SchoolClass newClass = new SchoolClass(className);
  newClass.setLayout(l);
  newClass.addTeacher(t1);
  t1.addClass(newClass);
  
  newClass.addTeacher(t2);
  t2.addClass(newClass);
  DataInsertionModule.insert(newClass);
  </code></pre>
  
  <p>This statement <code>DataRetrieveModule.getTeacher(id1)</code> opens a session, retrives the teacher by ID and closes it.
  <code>DataInsertionModule.insert(newClass)</code> also opens a session, calls  <code>session.saveOrUpdate(newClass)</code>. (I also tried <code>session.merge(newClass)</code>)</p>
  
  <p>Retrieving a teacher:</p>
  
  <pre><code>public static Teacher getTeacher(String id) {
          Session session = null;
          Teacher t = null;
          try{
              sessionFactory = MyFactory.getSessionFactory();
              session = sessionFactory.openSession();
              t = (Teacher) session.get(Teacher.class, Long.parseLong(id));
  
          }
          catch(Exception e) {
              System.out.println("in DAO:");
              e.printStackTrace();
              if(session!=null)
                  session.close();
          }       
          finally{
              if(session!=null)
                  session.close();
          }
  
          return t;
      }
  </code></pre>
  
  <p>Data insertion:</p>
  
  <pre><code>public static void insert(Object o) {
          Session session = null;
  
          try 
          {
              sessionFactory = MyFactory.getSessionFactory();
              session = sessionFactory.openSession();
              Transaction tx = session.beginTransaction();
  
              session.save(o);
              tx.commit();
  
              System.out.println("insertion done");
          }
          catch (Exception e)
          {
              System.out.println(e.getMessage());
              e.printStackTrace();
          }
          finally
          {
              if(session!=null)
                  session.close();
          }
      }
  </code></pre>
  
  <p>But insertion never works.
  There is always an object with the same id that already exists.</p>
  
  <pre><code>a different object with the same identifier value was already associated with the session: [creator.models.school.Teacher#3]
  </code></pre>
  
  <p>I searched on stackoverflow and have overridden my getHashCode and equals method in the class all my business objects inherit from:</p>
  
  <pre><code>@Override
  public int compareTo(Entity o) {
      if(this.id &lt; o.getId())
          return -1;
      else if(this.id &gt; o.getId())
          return 1;
      return this.getClass().getName().compareTo(o.getClass().getName());
  }
  
  @Override
  public boolean equals(Object o) {
      if(o instanceof Entity)
          return this.compareTo((Entity)o)==0;
      else return this.equals(o);
  }
  
  @Override
  public int hashCode() {
  
      char[] bla = this.getClass().getName().toCharArray();
      int blue=0;
      for(char c:bla)
          blue = blue*10 + c;
      return (int) (id+blue);
  
  }
  </code></pre>
  
  <p>Furthermore I tried to change the <code>CascadeType</code> of <code>ManyToMany</code> to <code>MERGE</code> (reverted again).</p>
  
  <p>At the moment I merge the teacher objects after retrieving both of them with session.get(..), as retrieving takes a lot of data out of the DB. There are futher  <code>..ToMany</code> relations. Therefore it probably might happen, that the call causes that both teachers are loaded. </p>
  
  <pre><code>public static Object merge(Object o) {
          Session session = null;
          Object returnVal = null;
          try 
          {
              sessionFactory = MyFactory.getSessionFactory();
              session = sessionFactory.openSession();
              Transaction tx = session.beginTransaction();
              returnVal = session.merge(o);
              tx.commit();
  
          }
          catch (Exception e)
          {
              System.out.println(e.getMessage());
              e.printStackTrace();
          }
          finally
          {
              if(session!=null)
                  session.close();
          }
          return returnVal;
      }
  </code></pre>
  
  <p>.</p>
  
  <pre><code>Teacher t1 = DataRetrieveModule.getTeacher(id1);
  Teacher t2 = DataRetrieveModule.getTeacher(id2);
  
  t1= DataInsertionModule.merge(t1);
  t2= DataInsertionModule.merge(t2);
  </code></pre>
  
  <p>Therefore I thought, that if I merge the one my get-method returned with the one that must have been loaded by the get call for the other teacher, it should work. (like here: <a href="http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/" rel="nofollow">http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/</a>) But it does not :(</p>
  
  <p>Is it probably because an object of the same superclass (Object or my Entity class) has the same ID? </p>
  
  <p>Please help me! </p>