2012-04-05 96 views
4

這是一個獨立的Java應用程序,而不是Web應用程序。所以,當我堅持的對象這樣JPA:如何在獨立Java應用程序中保留ID後

public <T> T create(T t) { 
    em.getTransaction().begin(); 
    em.persist(t); 
    em.flush(); 
    em.getTransaction().commit(); 
    return t; 
} 

idT t對象內仍無效,即使新行正確的數據,ID是數據庫中正確創建。通常在我的網絡應用程序中,使用@EJB,id在我堅持後立即可用,因爲它將實體對象持久化到我的持久化上下文中,我不確定在這裏是否有我的持久化上下文?

這是我映射我的ID我@Entity類中

@Id 
@Basic(optional = false) 
@Column(name = "ID") 
private Long id; 

也是我做這個表的id在數據庫AUTO_INCREMENT,這樣

CREATE TABLE Config 
(
    ID int NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (ID) 
) 

我這是怎麼獲得我的EntityManager

EntityManagerFactory emf = Persistence.createEntityManagerFactory("CorePU"); 
em = emf.createEntityManager(); 

這裏是我的內部persistence.xml

<persistence-unit name="CorePU" transaction-type="RESOURCE_LOCAL"> 
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>  
<class>com.wf.docsys.core.model.Config</class>  
<properties> 
    <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/XNINFODB"/> 
    <property name="javax.persistence.jdbc.password" value="xxx"/> 
    <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> 
    <property name="javax.persistence.jdbc.user" value="xxx"/> 
</properties> 

請幫幫忙,我不知道我做錯了什麼在這裏。

回答

0

這是我的答案。經測試

當從上面我所,這是

@Id 
@Basic(optional = false) 
@Column(name = "ID") 
private Long id; 

@Entity 
public class Person { 
    @Id 
    @TableGenerator(name="TABLE_GEN", table="SEQUENCE_TABLE", pkColumnName="SEQ_NAME", 
     valueColumnName="SEQ_COUNT", pkColumnValue="PERSON_SEQ") 
    @GeneratedValue(strategy=GenerationType.TABLE, generator="TABLE_GEN") 
    private long id; 
    ... 
} 

由於我使用Microsoft SQL Server映射您的ID,開關,我不得不使用@TableGenerator。更多的信息可以在這裏找到http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Table_sequencing

4

嘗試在您的ID字段中添加@GeneratedValue

1

正如我在this post上發現的那樣,EntityManager有一個名爲refresh的方法,在你堅持他之後會更新你的對象。

所以,你的代碼可能會是這樣的:

public <T> T create(T t) { 
    em.getTransaction().begin(); 
    em.persist(t); 
    em.refresh(t); 
    em.flush(); 
    em.getTransaction().commit(); 
    return t; 
} 

我沒有測試過這一點,所以我不知道哪兒放刷新方法調用,在那裏,提交後,經過沖水等

希望它可以幫助你。

祝你好運。

+4

刷新是不必要的。只要做flush()。這迫使堅持,並因此獲得id(一旦用戶添加了GeneratedValue註解當然)。 – DataNucleus 2012-04-06 10:59:53

+0

@DataNucleus:是的,我發佈了我的答案,因爲我不能使用'@ SequenceGenerator',我使用'@ GeneratedValue'@TableGenerator並且它可以工作。但是,每次調用'flush()'都會導致性能問題,DataNucleus? – 2012-04-06 13:05:26

+0

@DataNucleus:flush()爲我工作。你應該發佈一個答案。如果你精通足夠的話也可以解決Thang Pham的表現問題。 – user2316667 2014-06-23 19:11:28

1

我知道這不是堅持,但合併將更簡單地做同樣的事情。我把我的堅持包裹在一個實際的合併操作中,如果實體不存在,它將保存實體。

public T persist(T obj) { 
    EntityManager em = ThreadLocalPersistenceManager.getEntityManager(); 

    EntityTransaction tx = em.getTransaction(); 
    try { 
     tx.begin(); 
     obj = em.merge(obj); 
    } finally { 
     if (! tx.getRollbackOnly()) { 
      tx.commit(); 
     } 
    } 

    return obj; 
} 


/** 
* This will save the object and return the id of the persisted object. 
* 
* @param obj 
* @return The id of the persisted object. 
*/ 
public Long save(T obj) { 
    persist(obj); 
    return obj.getId(); 
}