JPA – Retour d’un identifiant généré automatiquement après persist ()

J’utilise JPA (EclipseLink) et Spring. Disons que j’ai une entité simple avec un ID généré automatiquement:

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

Dans ma classe DAO, j’ai une méthode d’insertion qui appelle persist() sur cette entité. Je veux que la méthode retourne l’ID généré pour la nouvelle entité, mais quand je le teste, il retourne 0 place.

 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; // ??? } } 

J’ai également une classe de service qui englobe le DAO, si cela fait une différence:

 public class ABCService { @Resource(name="ABCDao") ABCDao abcDao; public int addNewABC(ABC abc) { return abcDao.insertABC(abc); } } 

L’identification est uniquement garantie d’être générée au moment du nettoyage. La persistance d’une entité ne fait que la “rattacher” au contexte de persistance. Donc, soit vider le gestionnaire d’entités explicitement:

 em.persist(abc); em.flush(); return abc.getId(); 

ou renvoyer l’entité elle-même plutôt que son identifiant. Lorsque la transaction se termine, le vidage se produit et les utilisateurs de l’entité en dehors de la transaction verront donc l’ID généré dans l’entité.

 @Override public ABC addNewABC(ABC abc) { abcDao.insertABC(abc); return abc; } 
 @Entity public class ABC implements Serializable { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id; } 

vérifiez que la notation @GeneratedValue est présente dans votre classe d’entité. Cela indique à JPA le comportement de votre entité généré automatiquement

C’est comme ça que je l’ai fait:

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

Vous pouvez également utiliser GenerationType.TABLE au lieu de IDENTITY qui est uniquement disponible après l’insertion.

Une autre option compatible avec 4.0:

Avant de valider les modifications, vous pouvez récupérer le nouvel object CayenneDataObject partir de la collection associée au contexte, comme ceci:

 CayenneDataObject dataObjectsCollection = (CayenneDataObject)cayenneContext.newObjects(); 

puis accédez à ObjectId pour chacun dans la collection, comme:

 ObjectId objectId = dataObject.getObjectId(); 

Enfin, vous pouvez effectuer une itération sous les valeurs, où l’ID généré sera généralement la première des valeurs (pour une seule clé de colonne) dans la carte renvoyée par getIdSnapshot() , il contient également le ou les noms de colonne associés. à la PK comme clé (s):

 objectId.getIdSnapshot().values() 
 em.persist(abc); em.refresh(abc); return abc;