# [Hibernate] Objekt laden, Id ändern und speichern?



## poffi (27. Apr 2007)

Hallo zusammen

Eine DAO-Methode die ich gebastelt habe, sollte folgendes machen:
- Sie lädt ein Objekt
- Ändert und Updatetet das Objekt
- Ändert es erneut und speichert es als eine neues Objekt

Alle diese Dinge müssen zwingend in einer Session abgearbeitet werden (wegen bestimmten lazy-Dingen).
Das Problem liegt beim letzten Schritt. Da ich ein neues Objekt in der Datenbank haben will, ändere ich die ID, sprich den Primarykey auf null. Das schluckt Hibernate aber nicht, es reklamiert, dass das Objekt eine falsche ID hat. Würde ich das Ganze verteilt in zwei Sessions erledigen, würde Hibernate dem Objekt problemlos eine neue ID zuordnen.

Meine Frage ist nun also, wie ich es hinkriege, dass ich in einer Session ein Objekt unter einer anderen Id abspeichern bzw. es duplizieren kann?

Danke im Voraus!


----------



## KSG9|sebastian (27. Apr 2007)

Die Objekte sind mit der Session verbunden, deshalb kannst du dei ID nicht ändern.
Aber so wie ich das sehe:


```
public void changeObject(Serializable id){
  Session session = HibernateSessionFactory.currentSession();
  Transactino tx = session.beginTransaction();
  try{
     Daten d = (Daten)session.get(id);
     d.setText("ein anderer text");
     d.setBemerkung("Text geändert...");
     session.attacheDirty(d);
     Daten dNeu = new Daten();
     dNeu.setText(d.getText());
     dNeu.setBemerkung(d.getBemerkung());
     session.save(dNeu);
     if(tx != null){
       tx.commit();
     }
  } catch(HibernateException e){
     if(tx != null){
        tx.rollback();
     }
  }
}
```

Was natürlich nicht geht ist folgendes

- Objekt ändern
- Objekt updaten in der db
- Objekt ändern
- Objekt neu speichern

denn dann kriegst du ne Exception dass die ID schon in der DB vorhanden ist. Du musst den umweg gehen über neues Objekt erzeugen und Properties kopieren (bis auf die ID).

Gruß Sebastian

*** Edit ***

besser als jedes Property einzeln zu kopieren:



```
public void changeObject(Serializable id){
  Session session = HibernateSessionFactory.currentSession();
  Transactino tx = session.beginTransaction();
  try{
     Daten d = (Daten)session.get(id);
     d.setText("ein anderer text");
     d.setBemerkung("Text geändert...");
     session.attacheDirty(d);
 
     Daten dNeu = (Daten)HibernateBeanReplicator.dupEntityBean(d);
     dNeu.setId(null);
     session.save(dNeu);
     
     if(tx != null){
       tx.commit();
     }
  } catch(HibernateException e){
     if(tx != null){
        tx.rollback();
     }
  }
}
```


----------



## poffi (27. Apr 2007)

Vielen Dank Sebastian!

Ich hatte auch die Idee, eine neue Instanz zu erstellen und dann die Properties zu kopieren. Leider bekomme ich dabei wieder Probleme mit weiteren Beziehungen, die das Objekt hat. Die Exception "Found shared references to a collection", wird beim Speichern ausgegeben. Sie bezieht sich auf ein Set-Mapping.

Deine zweite Variante sieht sehr vielversprechend aus, kann mir gut vorstellen, das Hibernate das "Shared References"-Problem beseitigt. Irgendwie habe ich aber nur die org.hibernate.*-Packages zur Verfügung. Die statische Methode HibernateBeanReplicator.dupEntityBean(d); ist aber nur im Package net.sf.beanlib.hibernate.* vorhanden.

Dumme Frage, aber wo liegt der Unterschied zwischen diesen Packagen? Sind das einfach weitere Hilfklassen?

THX!


----------

