2012-03-16 11 views
77

私はJPA(EclipseLink)とSpringを使用しています。私は、自動生成されたIDを持つ単純な実体持っていると言う:私のDAOクラスでJPA - persist()後に自動生成されたIDを返す

@Entity 
public class ABC implements Serializable { 
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id; 

    // ... 
} 

を、私はこのエンティティにpersist()を呼び出すinsertメソッドを持っています。私はメソッドが新しいエンティティのために生成されたIDを返すようにしたいが、私がそれをテストすると0を代わりに返す。 IDが唯一のフラッシュ時に生成されることが保証されて

public class ABCService { 
    @Resource(name="ABCDao") 
    ABCDao abcDao; 

    public int addNewABC(ABC abc) { 
     return abcDao.insertABC(abc); 
    } 
} 
+0

同様のものについてはJPAに伝えますhttp://stackoverflow.com/q/3328813/366964 –

+0

お返事ありがとうございます。そして、(JPAではなく)難解な解決策として、私たちはunixタイムスタンプのような別の一意のIDを使うことができます。 – sura2k

+1

JPAは@GeneratedValue @Idをいつ設定するのですか?(http://stackoverflow.com/questions/9087848/when-does-the-jpa-set-a-generatedvalue-id) – Raedwald

答えて

121

:それは違いを作る場合

public class ABCDao { 
    @PersistenceContext 
    EntityManager em; 

    @Transactional(readOnly=false) 
    public int insertABC(ABC abc) { 
     em.persist(abc); 
     // I WANT TO RETURN THE AUTO-GENERATED ID OF abc 
     // HOW CAN I DO IT? 
     return abc.id; // ??? 
    } 
} 

は、私はまた、DAOをラップサービスクラスを持っています。エンティティを永続化することは、永続化コンテキストに「接続」させるだけです。したがって、エンティティマネージャを明示的にフラッシュするか、IDではなくエンティティ自体を返します。トランザクションが終了すると、フラッシュが行われ、トランザクション外のエンティティのユーザーは、エンティティ内で生成されたIDを確認します。

@Override 
public ABC addNewABC(ABC abc) { 
    abcDao.insertABC(abc); 
    return abc; 
} 
+6

NB:これが必要ですidフィールドを '@ GeneratedValue'でアノテートする - それが何であれ、 –

+0

複合IDでこれを達成しようとする際の問題を説明してください。http://stackoverflow.com/questions/31362100/explain-behaviors-in-mapping-auto -incremented-composite-id-sequence-with-hiberna – bl3e

+0

永続化した後で手動でフラッシュするとパフォーマンス上のペナルティ(またはその他の悪影響)がありますか? –

-1
em.persist(abc); 
em.refresh(abc); 
return abc; 
+0

この方法は私のためには機能しませんでした。このエラーが発生しました:javax.persistence.PersistenceException:org.hibernate.HibernateException:このインスタンスはまだデータベースの行として存在しません – rtcarlson

+0

@rtcarlson、はいこれは動作しません。新しいオブジェクトを作成する場合、必要なのは 'em.refresh(abc)'ではなく 'em.flush()'です。 –

2

また、代わりに挿入した後にのみ使用可能ですIDENTITYのGenerationType.TABLEを使用することができます。

1

これは私がそれをやった方法です:@GeneratedValue表記は、あなたのエンティティclass.Thisであることを

EntityManager entityManager = getEntityManager(); 
EntityTransaction transaction = entityManager.getTransaction(); 
transaction.begin(); 
entityManager.persist(object); 
transaction.commit(); 
long id = object.getId(); 
entityManager.close(); 
+0

テーブルにデータを永続化した後、Returnとしてゼロを与えていない。いずれかのリフレッシュはこのケースでは動作していません..私はこれのために何をすべきですか?どうか提案してください...ありがとうございました –

+0

@VikrantKashyap新しいコードを小さなコードで投稿してください。 –

6
@Entity 
public class ABC implements Serializable { 
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id; 
} 

チェックは、あなたのエンティティプロパティの自動生成動作

関連する問題