Warum müssen wir manuell flush() des EntityManager in einem extended PersistenceContext?
In unserer J2EE-Anwendung verwenden wir eine EJB-3 stateful bean zu ermöglichen, die vor-code zu erstellen, ändern und speichern von persistenten Entitäten (managed durch JPA-2).
Es sieht wie folgt aus:
@LocalBean
@Stateful
@TransactionAttribute(TransactionAttributeType.NEVER)
public class MyEntityController implements Serializable
{
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;
private MyEntity current;
public void create()
{
this.current = new MyEntity();
em.persist(this.current);
}
public void load(Long id)
{
this.current = em.find(MyEntity.class, id);
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void save()
{
em.flush();
}
}
Sehr wichtig, um zu vermeiden, zu früh verpflichtet, nur die save()
Methode innerhalb einer Transaktion ist, so nennen wir create()
wir legen nichts in die Datenbank.
Neugierig, in der save()
Methode, wir nennen em.flush()
um wirklich der hit-Datenbank. In der Tat, ich habe versucht, und fand, dass wir es auch nennen em.isOpen()
oder em.getFlushMode()
, sowie alles, was ist "em-Bezug".
Verstehe ich nicht diesem Punkt. Als save()
ist in einer Transaktion, dachte ich, dass am Ende der Methode wird die Transaktion committed, und so die persistenten entity-manager automatisch gespült. Warum muss ich manuell Spülen Sie es?
Dank,
Xavier
- Keine Notwendigkeit zu
flush()
.joinTransaction()
sollte genug sein, um die änderungen zu speichern in Ihren Transaktions-Methode.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Direkt zu sein und an der Metall, wird es keine
javax.transaction.Synchronization
Objekte registriert, die für den EntityManager in Frage, bis Sie wirklich verwenden es in einer Transaktion.Wir in app-server-land erstellen dieser Objekte zu tun, die
flush()
und registrieren Sie es mit derjavax.transaction.TransactionSynchronizationRegistry
oderjavax.transaction.Transaction
. Dies kann nicht getan werden, es sei denn, es wird eine aktive Transaktion.Das ist die lange und die kurze davon.
Ja, ein app-server konnte sehr gut halten, eine Liste von Ressourcen gab es die stateful bean und auto anmelden, sind Sie in jeder Transaktion, die stateful bean könnte starten oder daran teilnehmen. Der Nachteil daran ist, dass man komplett verlieren die Fähigkeit zu entscheiden, welche Dinge gehen, in denen Transaktionen. Haben Sie vielleicht eine 2 oder 3 verschiedene Geschäfte zu laufen auf unterschiedlichen persistence-units und die Verdichtung der Arbeit in Ihrer Erweiterten Persistenz-Kontext für eine ganz bestimmte Transaktion. Es ist wirklich ein design-Problem und der app-server lassen sollte, solche Entscheidungen zu der app selbst.
Verwenden Sie es in einer Transaktion, und wir werden registrieren Sie sich in der Transaktion. Das ist der grundlegende Vertrag.
Side note, je nachdem, wie die zugrunde liegenden EntityManager behandelt wird, alle persistent Aufruf der EntityManager kann werden genug, um zu einem vollständigen flush am Ende der Transaktion. Sicherlich
flush()
ist die direkte und klar ist, aber einpersist()
oder sogar einfind()
könnte es tun.If the entity manager is invoked within a JTA transaction, the persistence context will be associated with the JTA transaction
.Wenn Sie erweiterte persistenzkontext alle Operationen auf den verwalteten Entitäten erfolgt innerhalb der nicht-transaktionale Methoden sind in der Warteschlange werden in die Datenbank geschrieben. Sobald Sie call flush() auf entity-manager innerhalb einer Transaktion Kontext alle in die Warteschlange änderungen in die Datenbank geschrieben werden. Also in anderen Worten, die Tatsache, dass Sie eine Transaktions-Methode nicht die änderungen selbst, wenn die Methode beendet (wie bei CMT), aber die Spülung entity manager eigentlich tut. Sie finden die vollständige Erklärung dieses Prozesses hier
Da es keine Möglichkeit gibt zu wissen "Wann" der client die Sitzung (erweiterter Umfang).