133 votes

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 souhaite que la méthode renvoie l'ID généré pour la nouvelle entité, mais lorsque je la teste, elle renvoie à la place 0 .

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

215voto

JB Nizet Points 250258

La génération de l'ID n'est garantie qu'au moment du vidage. La persistance d'une entité la rend seulement « attachée » au contexte de persistance. Donc, soit videz explicitement le gestionnaire d'entités :

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

ou renvoyer l'entité elle-même plutôt que son ID. Lorsque la transaction se termine, le flush se produira, et les utilisateurs de l'entité en dehors de la transaction verront ainsi l'ID généré dans l'entité.

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

14voto

utkal patel Points 251
@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 généré automatiquement par votre propriété d'entité

5voto

Koray Tugay Points 1885

Voici comment j'ai procédé :

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

2voto

James Points 18355

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X