# detached entity passed to persist



## peez (22. Nov 2010)

Ich habe gerade ein Problem wo ich nicht weiter komme...

Ich habe eine Stateless Session Bean namens "BenutzeverwaltungrBean":

```
@Stateless( name = "BenutzerverwaltungBean" )
public class Benutzerverwaltung implements BenutzerverwaltungLocal, BenutzerverwaltungRemote {
	@Override
	public Benutzer findBenutzerByName( String name ) throws NotFoundException {
		Query query = em.createQuery( "SELECT b FROM Benutzer b WHERE b.name = :name" );
		query.setParameter( "name", name );
		List<Benutzer> result = query.getResultList();

		if ( result.size() == 0 ) {
			throw new NotFoundException();
		}

		return result.get( 0 );
	}

	@Override
	public Benutzer saveBenutzer( Benutzer benutzer ) {
		try {
			em.merge( benutzer );
			em.persist( benutzer );
		} catch (Exception e) {
			e.printStackTrace();
		}

		return benutzer;
	}
}
```

Vom Client aus mache ich folgendes:

```
BenutzerverwaltungRemote bv = ...; //Lookup
Benutzer b = bv.findBenutzerByName( "username" );
System.err.println( b.getId() ); //Hier kommt auch die richtige ID raus
b.setVorname( "EinVorname" );
bv.saveBenutzer( b ); //Speichern
```

Beim Speichern des Benutzers in der Zeile mit em.persist() bekomme ich dann die PersistentObjectException:


```
19:57:04,190 ERROR [STDERR] javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: de.test.dpmam.common.businessobjects.Benutzer

19:57:04,195 ERROR [STDERR] 	at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1160)

19:57:04,197 ERROR [STDERR] 	at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1094)

19:57:04,199 ERROR [STDERR] 	at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1103)

19:57:04,201 ERROR [STDERR] 	at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:603)

19:57:04,203 ERROR [STDERR] 	at org.jboss.jpa.impl.tx.TransactionScopedEntityManager.persist(TransactionScopedEntityManager.java:206)

19:57:04,204 ERROR [STDERR] 	at de.test.dpmam.server.beans.Benutzerverwaltung.saveBenutzer(Benutzerverwaltung.java:193)
```


Mache ich das falsch?


----------



## Gelöschtes Mitglied 5909 (22. Nov 2010)

merge und persist auf einmal ist schlecht.


```
if (em.contains(benutzer) {
  em.merge(benutzer);
} else {
 em.persist(benutzer);
}
em.flush();
```

// edit 
richtiger ist eigentlich folgendes:

```
if (benutzer.getId() != null) {
  em.merge(benutzer);
} else {
 em.persist(benutzer);
}
em.flush();
```

Aber du hast ja nicht geschrieben ob du eine id hast oder nicht (sogut wie immer ratsam)


----------



## peez (22. Nov 2010)

Super so gehts! :toll::toll:

So langsam fange ich an zu verstehen... 

Vielen Dank fürs Aufklären!


----------



## turmaline (12. Jan 2011)

Hallo,

ich habe auch Problem mit merge und persist. Ich habe auf der Client- und auf der Server-Seite eine Datenbank. Ein Feedback wird auf der Client-Seite erstellt, einige seiner Attribute dürfen auf der Server-Seite geändert werden, einige auf der Client-Seite. Dies muss dann synchronisert werden.

Für das Mergen auf der Client-Seite benutze ich folgende Methode:


```
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    private Feedback mergeByFeedbackUUID(Feedback feedback) {
        String uuid = feedback.getFeedbackUUID();
        List<Comment> newComments = feedback.getComments();
        if (uuid != null) {
            Feedback feedback2 = findFeedback(uuid);
            if(feedback2!=null) {
                List<Comment> feedbackComments = feedback2.getComments();
                feedback.setComments(feedbackComments);
                feedback.addComments(newComments);
                feedback.setId(feedback2.getId());
                feedback.setContent(feedback2.getContent());
                feedback.setReadyToSync(feedback2.getReadyToSync());
            } else {
                throw new RuntimeException("Feedback with id " + uuid + " does not exist");
            }
            feedback = _em.merge(feedback);
        }
        return feedback;
    }
```

Die id von den Feedbacks auf der Client- und Server-Seite kann sich unterscheiden. Nachdem der Feedback gemergt wird sollten einige seiner Attribute sich ändern. Wenn ich die DB wieder abfrage, sehe ich dass die geänderten Attribute nicht upgedatet wurden.
Hat jemand eine Ahnung woran das liegt?

Wenn ich danach persist aufrufe, bekomme ich dieselbe deteached entity ex.

Warum werden die Änderungen mit merge nicht gespeichert? ???:L

Gruß,
madlena


----------



## peez (12. Jan 2011)

Ich kann dir leider mit deinem Problem nicht helfen, da ich noch nie mit Spring gearbeitet habe (Feedback und @Transactional ist doch Spring oder?). Aber mach am Besten nen komplett neuen Thread dazu auf. Wird wahrscheinlich dann eher gelesen.


----------



## Gelöschtes Mitglied 5909 (12. Jan 2011)

1. mach mal ei flush() dazu.
2. was sagt das logging?


----------

