2016-03-21 24 views
0

我在PostgreSQL中創建表和序列:Glassfish的實體不會保持

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 
); 

然後我在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; 
    } 

} 

然後我嘗試從servlet的寫我的表實體:

@PersistenceUnit(name="Tets") 
EntityManagerFactory emf; 

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     // TODO Auto-generated method stub 
     EntityManager em = emf.createEntityManager(); 
     Test t = new Test(); 

     t.setName("jdsfjjd"); 
     t.setName2("jdsfjjd"); 
     em.persist(t); 

     response.getWriter().append("Served at: ").append(request.getContextPath()); 
    } 

當我部署我的項目並使用該servlet時,我沒有看到日誌。項目部署servlet是開始,在瀏覽器中我看到:Served at: /Tets,但是當我檢查表時,我沒有在那裏看到我的實體。我究竟做錯了什麼?

+0

em.persist(..)' – Jens

+0

我添加和catch javax.persistence.TransactionRequiredException後''加em.flush()'沒有外部管理的事務是目前這個線程 – JugerJuger

+0

你必須主動配置事務管理器 – Jens

回答

0

簡短的回答:你濫用應用程序管理的EntityManager。

在Java EE環境中注入EntityManager時,它由IoC容器控制(它幾乎總是EJB或CDI)。集裝箱處理業務方法的調用使得在交易機制的任何手動操作不必要的交易傳播和分界:

@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 

當你,而不是注入EntityManagerFactory的,所有的魔法就會消失。在這種情況下,您需要手動執行事務性綁定。你什麼都不做,這就是你得到TransactionRequiredException的原因。原始示例不會拋出任何內容,因爲如果沒有活動事務,則不會發生刷新,因此您的更改將被默認忽略。這看起來就像這樣:

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

在這種情況下,我建議你使用EntityManager的注射連同一些無國籍豆保持EM的線程不安全利用行業的最佳實踐。然後將你的EJB注入到這個servlet中,並執行你所需要的。

另一種方法是注入UserTransaction並明確地調用它的begin()方法。 UserTransaction沒有聲明爲線程安全的,因此您需要圍繞它的用法進行某種同步。這絕對會殺死所有的表演,所以我建議你回到第一個選項。 異常說明: