2016-03-21 15 views
0

I create table und Reihenfolge in PostgreSQL:Glassfish Einheit wird nicht beibehalten

CREATE SEQUENCE 
    test_id 
INCREMENT 1 
START 1 
MAXVALUE 500; 
CREATE TABLE TEST(
    id    NUMERIC PRIMARY KEY DEFAULT NEXTVAL('test_id'), 
    name    TEXT NOT NULL UNIQUE, 
    name2    TEXT DEFAULT NULL 
); 

Dann generiere ich Einheit in Eclipse:

@Entity 
@NamedQuery(name="Test.findAll", query="SELECT t FROM Test t") 
public class Test implements Serializable { 
    private static final long serialVersionUID = 1L; 
    private long id; 
    private String name; 
    private String name2; 

    public Test() { 
    } 


    @Id 
    @SequenceGenerator(name="TEST_ID_GENERATOR", sequenceName="TEST_ID", allocationSize=1) 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="TEST_ID_GENERATOR") 
    public long getId() { 
     return this.id; 
    } 

    public void setId(long id) { 
     this.id = id; 
    } 


    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 


    public String getName2() { 
     return this.name2; 
    } 

    public void setName2(String name2) { 
     this.name2 = name2; 
    } 

} 

Dann versuche ich meine Einheit in der Tabelle von Servlet zu schreiben:

Wenn ich mein Projekt bereitstellen und dieses Servlet verwende, sehe ich keine Protokolle. Project ist deploy Servlet ist Start, im Browser sehe ich: , aber wenn ich die Tabelle überprüfe, sehe ich meine Entität dort nicht. Was mache ich falsch?

+0

hinzufügen 'em.flush()' 'nach em.persist (..)' – Jens

+0

i hinzufügen und fangen javax.persistence.TransactionRequiredException: Exception Beschreibung: Keine extern verwalteten Transaktion derzeit aktiv für diesen Thread – JugerJuger

+0

Sie müssen Konfigurieren Sie einen Transaktionsmanager – Jens

Antwort

0

Die kurze Antwort: Sie missbrauchen Application-Managed EntityManager.

Wenn Sie einen EntityManager in eine Java EE-Umgebung injizieren, wird er von Ihrem IoC-Container gesteuert (es ist fast immer EJB oder CDI). Container behandelt Transaktionen Ausbreitung und Abgrenzung auf Abruf Business-Methode alle manuellen Aktionen auf Transaktionsmechanismen machen unnötigen:

@PersistenceContext 
private EntityManager em; 
... 
@TransactionAttribute(REQUIRES_NEW) 
public void someMethod(Bean b) { 
    em.persist(b); 
} // Transaction gets committed and em gets flushed with no extra work 

Wenn Sie eine EntityManagerFactory statt injizieren, die ganze Magie verschwunden sein würde. In diesem Fall müssen Sie die Transaktionsbindung manuell ausführen. Sie tun nichts dagegen und deshalb erhalten Sie TransactionRequiredException. Im ursprünglichen Beispiel wird nichts ausgegeben, da ohne aktive Transaktion kein Flush erfolgt. Ihre Änderungen werden daher ignoriert. Dies würde so aussehen so:

@Resource 
private UserTransaction t; 
... 
t.begin(); 
emf.createEntityManager().persist(bean); 
t.commit(); 

In diesem Szenario, das ich Ihnen vorschlagen würde durch die Verwendung EntityManager Injektion in Verbindung mit einigen stateless Bean branchenweit beste Praxis zu nutzen EM Thread unsafety zu halten. Dann injiziere dein EJB in dieses Servlet und mache, was du brauchst.

Die andere Möglichkeit wäre, UserTransaction zu injizieren und die Methode begin() explizit aufzurufen. UserTransaction ist nicht als threadsicher deklariert, daher benötigen Sie eine Art Synchronisation für die Verwendung. Dies wird definitiv alle Leistung zu töten, also würde ich vorschlagen, dass Sie auf die erste Option zurückfallen.