2012-10-27 5 views
6

Ich benutze Hibernate 4.1.7 und versuche, Objekt zu aktualisieren, aber es gibt keine Dokumentation, wie es gemacht werden sollte. Derzeit ich dies tue:Hibernate Update mit EntityManager

Person person = personDao.getPersonById(1); 
    person.setAge(23); 
    person.setLastname("McName"); 
    person = personDao.update(person); 

In PersonDao Update wie folgt aussieht:

public Person update(Person person) { 
     return entityManager.merge(person); 
    } 

In PersonDao getPersonById ist:

public Person getPersonById(int id) { 
     personQuery = entityManager.createNamedQuery("Person.findPerson", Person.class); 
     personQuery.setParameter("id", id); 
     return personQuery.getSingleResult(); 
    } 

Auch habe ich definiert benannte Abfrage innerhalb Person-Klasse und ist hier:

@NamedQuery(name="Person.findPerson", query="SELECT p FROM Person p WHERE p.id = :id") 

Durch die Verwendung meiner Person wird nicht aktualisiert, wie sollte ich Update mit Hibernate implementieren?

+0

Der obige Code ist in Ordnung, außer dass der Aufruf von 'personDao.update()' völlig unnötig ist, wenn alles in einer einzigen Transaktion ausgeführt wird: der Zustand eines Unternehmens wird automatisch persistent von JPA/Hibernate bei das Ende der Transaktion. Die getPersonById-Methode könnte auch auf em.find (Person.class, id) reduziert werden, was einfacher und effizienter wäre, da sie keine Abfrage ausführen würde, wenn die Entität bereits geladen ist. –

+0

Nachtrag: Dies wird in der Dokumentation eindeutig erklärt. Siehe http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html_single/#d5e772 –

Antwort

4

Zwei Szenarien könnten für Sie auftauchen.

Möglicherweise möchten Sie eine Eigenschaft des Objekts und nur diese Eigenschaft ändern.

Wenn dies der Fall ist, möchten Sie die Methode verwenden: Find, Modify, Flush, Commit.

em.find(Person.class, person.getId()) 
person.setStatus("ACTIVE"); 
em.commit();//implicitly flushes if flush mode is COMMIT or AUTO. 

Sie sollten die Objekte Eigenschaften verwenden, um das Element zu aktualisieren.

Wenn dies der Fall ist, möchten Sie die Methode verwenden: Zusammenführen, optional ändern, Flush, Commit.

em.merge(person); 
//modify person if you wish. 
em.commit();//implicitly flushes if flush mode is COMMIT or AUTO. 
+0

Gefunden meine Lösung, schließlich habe ich entityManager.getTrasaction(). Begin(); person = entityManager.find (Person.class, id); entityManager.merge (Person); // Personendaten ändern entityManager.getTransaction(). Commit(); – Timo

+0

Froh, dass Sie eine Lösung gefunden haben. Wenn die ID, die während der Suche verwendet wird (Person.class, id), die Person.id ist, die beim Zusammenführen (Person) verwendet wird, ist die Zusammenführung möglicherweise nicht erforderlich. Sobald Sie die Suche durchgeführt haben, wird Ihre Entität verwaltet und Sie können Ihre Änderungen bearbeiten und festschreiben. – dseibert

0

Ich weiß nicht, was Sie genau sind gefragt, aber in Ihrer Methode, Person.getPersonById(int id), können Sie Ihren Code mit den folgenden vereinfachen:

return entityManager.find(Person.class, id); 
1

Hibernate und auch anderen JPA-Implementierungen automatisch Zustand von Entitäten verwalten und speichern Sie es in der Datenbank, wenn die Änderung in der Transaktion enthalten ist. Sie müssen nicht explizit die Methoden merge oder update aufrufen.

Wenn Sie Ressource-lokale Transaktionen verwenden (nicht von JTA Transaktionsmanager geführt werden) versuchen, etwas wie folgt aus:

EntityTransaction tx = entityManager.getTransaction(); 
tx.begin(); 
Person person = personDao.getPersonById(1); 
person.setAge(23); 
person.setLastname("McName"); 
tx.commit(); 

und alle Ihre Änderungen automatisch in der Datenbank gespeichert werden.

Wenn Sie JTA verwenden, müssen Sie die Transaktionsgrenzen auf andere Weise markieren, z. B. mit Spring AOP @Transactional Annotation.

+0

Ich benutze hsqldb (resource-local) und mit diesem Code bekomme ich die Ausnahme: org.hibernate. PersistentObjectException: losgelöste Entität, die an persist übergeben wurde: com.application.model.Person – Timo

+0

Wahrscheinlich verwenden Sie zwei unterschiedliche Instanzen von EntityManager. – Jarek