J'utilise JPA (EclipseLink) et Spring. Disons que j'ai une entité simple avec un identifiant 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 retourne l'ID généré pour la nouvelle entité, mais lorsque je la teste, elle renvoie plutôt 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);
}
}
L'identification n'est garantie que lors de la génération. La persistance d'une entité ne la rend que "rattachée" au contexte de persistance. Donc, soit vider 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 identifiant. Lorsque la transaction se termine, le vidage aura lieu et les utilisateurs de l'entité extérieure à la transaction verront ainsi 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 figure dans votre classe d'entités. Cela indique à JPA le comportement généré automatiquement par votre propriété d'entité
Voici comment 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 n'est disponible qu'après l'insertion.
Voici comment je l'ai fait. Tu peux essayer
public class ABCService {
@Resource(name="ABCDao")
ABCDao abcDao;
public int addNewABC(ABC abc) {
ABC.setId(0);
return abcDao.insertABC(abc);
}
}
Une autre option compatible à 4.0:
Avant de valider les modifications, vous pouvez récupérer le ou les nouveaux objets CayenneDataObject
de la collection associée au contexte, comme suit:
CayenneDataObject dataObjectsCollection = (CayenneDataObject)cayenneContext.newObjects();
ensuite, accédez à la ObjectId
pour chacun dans la collection, comme:
ObjectId objectId = dataObject.getObjectId();
Enfin, vous pouvez effectuer une itération sous les valeurs. Généralement, l'id-généré sera la première des valeurs (pour une clé de colonne unique) dans la carte renvoyée par getIdSnapshot()
. PK comme clé (s):
objectId.getIdSnapshot().values()