2012-04-05 4 views
4

これはスタンドアロンのJavaアプリケーションであり、Webアプリケーションではありません。私はT tオブジェクト内のこのJPA:スタンドアロンJavaアプリケーションで永続化した後にIdを取得する方法

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

idのようなオブジェクトを永続化するときに、正しいデータとidを持つ新しい行がデータベース内で正しく作成されていても、まだnullです。通常、私の永続コンテキストにエンティティオブジェクトを永続させるので、@EJBを利用する私のWebアプリケーションでは、idを利用できるようになりました。ここに永続コンテキストがあるかどうかわかりません。

これは、私も、私はこれは私が入手する方法です。この

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

のように、データベースAUTO_INCREMENTで、このテーブルのIDを作る私の@Entityクラス

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

内の私の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

が私の答えです。私は、Microsoft SQL Serverを使用しているので、私は@TableGeneratorを使用する必要が

@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; 
    ... 
} 

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

である、あなたのイドをマッピングする場合

テストされ、私は上記の持っているものからスイッチ。詳細はこちらをご覧ください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

リフレッシュが不要です。ただフラッシュする()。それは永続性を強制し、idを取得します(ユーザーがもちろんGeneratedValueアノテーションを追加した後)。 – DataNucleus

+0

@DataNucleus:私は '@ SequenceGenerator'を使うことができないので、以下の答えを投稿しました。' @TableGenerator 'を '@ GeneratedValue'と一緒に使っています。しかし、毎回 'flush()'を呼び出すと、パフォーマンスの問題DataNucleusが発生しますか? –

+0

@DataNucleus:flush()が私のために働いていました。あなたは答えを投稿するべきです。 Thang Pham氏の業績への懸念にも十分にお答えいただければ幸いです。 – user2316667

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(); 
} 
関連する問題