Bonjour.
Je gère ma persistence avec JPA. Mon problème est de pouvoir récupérer l'ID de la ligne que je viens de persister pour l'utiliser ailleurs. Seulement, la méthode persist de l'EM ne retourne rien. est-il possible de le faire?
Version imprimable
Bonjour.
Je gère ma persistence avec JPA. Mon problème est de pouvoir récupérer l'ID de la ligne que je viens de persister pour l'utiliser ailleurs. Seulement, la méthode persist de l'EM ne retourne rien. est-il possible de le faire?
Si un autre objet géré par l'entity manager doit référencer l'id du premier, alors tu as un problème de design, il devrait référencer l'objet et non pas son id ;)
Pour le reste, si tu fais un flush de ton entitymanager, un id devrait être attribué à l'objet et tu peux donc faire un getId() dessus pour le connaître.
non! le second objet ne doit pas être généré par l'EM.
le flush me génère une erreur
en fait l'id de l'objet en est null et j'imagine que lorsque je un refresh(en), l'EM ne sais pas avec quelle ligne de la BD synchroniser, donc me renvoie une erreur.Code:
1
2
3
4
5
6 public T save1(T en) { getEntityManager().persist(en); getEntityManager().refresh(en); return en; }
j'ai cependant utiliser ce code:
un merge pour réattacher en à l'EM, mais l'id généré ne correspond pas à celui qui est présent dans la bd. il y a pas une façon de récupérer l'id avec un currval comme on le fait en plpgsql?Code:
1
2
3
4
5
6
7 public T save1(T en) { getEntityManager().persist(en); en = (T) getEntityManager().merge(en); getEntityManager().refresh(en, LockModeType.NONE); return en; }
Quelle erreur il te génère? Je ne vois pas de flush dans ton code :weird: flush et refresh, ce n'est pas la même chose.
Oui tu as raison merci, c'est une erreur en fait dans le code c'est bien un flush pour synchroniser l'entity avec sa version persisté. Mais :aie:.
l'id généré n'a rien à voir avec l'id de l'instance que je viens de persister. et très franchement j'ignore à quoi correspond cet id.
j'ai fait l'insertion dans une autre table en utilisant la même méthode et là je réalise qu'en fait l'EM génère pour cet autre entity un id qui suit directement le précédent. En d'autres terme, il se conduit comme si toutes les entités étaient insérer dans la même table
l'entity manager génère les id suivant les règles que tu lui a imposé, via sa configuration. Du coup, j'en viens à me demander ce que tu appelle l'id généré et ce que tu appelle l'id de l'instance, vu qu'il ne devrait y avoir qu'un seul id :weird:
Je vais tout t'expliquer par un exemple:
là c'est le code de l'entité à persister
la méthode de persistance estCode:
1
2
3
4
5
6
7
8
9
10
11 @Entity public class Entite implements Serializable{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", columnDefinition = "BIGSERIAL") private Long id; ...... les autres attributs }
lorsque je faitCode:
1
2
3
4
5
6 public T save1(T en) { getEntityManager().persist(en); getEntityManager().flush(); return en; }
j'obtiens par exemple 100.Code:System.out.println(en.getId())
je regarde dans la base de donnée et la séquence auto-généré est 12.
comment explique-t-on ça? et surtout comment avoir 12 juste après l'insertion? Merci encore
d'un coté, tu parle de identity, et de l'autre de sequence. Tu es sûr que tu n'aurais pas un code supplémentaire, dans ta base de données, genre un trigger, qui changerais l'id après l'insertion? Ca expliquerait pourquoi la base de données n'a pas la même valeur que l'entity manager.
Merci tchize_ le problème vient justement du fait que j'ai négligé la pertinence des valeur Identity et Sequence. le flush fonctionne bien maintenant.
Merci encore c'était si proche
Ceci dit, je suis d'avis que tu as utilisé la mauvaise méthode, comme le disait tchize_, il faudrait référencer l'objet parent.
Peut-être même persister en utilisant l'attribut cascade sur le père... mais ça dépend des cas d'usages là...
Comme il l'a dit, l'autre objet n'est pas géré par l'EM, donc probablement même pas stocké dans une DB. Log, url dans un email, .... il peut y avoir des tas de raisons de récupérer l'id :)