Est-il un moyen de passer détaché de l'objet à JPA persistent? (détaché de l'entité passée à persister)
J'ai 2 entités : Account
et AccountRole
.
public class Account {
private AccountRole accountRole;
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
public AccountRole getAccountRole() {
return accountRole;
}
.
public class AccountRole {
private Collection<Account> accounts = new ArrayList<Account>();
@OneToMany(mappedBy = "accountRole", fetch = FetchType.EAGER)
public Collection<Account> getAccounts() {
return accounts;
}
Problème vient lorsque je prends la accountRole à partir de la base de données et essayez de conserver mon Account
. À ce point, je viens de créer mon compte et le rôle existe déjà dans la base de données.
AccountRole role = accountService.getRoleFromDatabase(AccountRoles.ROLE_USER);
account.setAccountRole(role);
//setting both ways, as suggested
public void setAccountRole(AccountRole accountRole) {
accountRole.addAccount(this);
this.accountRole = accountRole;
}
entityManager.persist(account); //finally in my DAO
J'ai lu ceci : JPA/Hibernate: détaché entité passé à persister Et ce que j'ai compris, je dois définir les entités valeurs des deux sens, de sorte que ce que je fais dans mon setter.
Encore avoir d'erreur.
org.hibernate.PersistentObjectException: detached entity passed to persist: foo.bar.pojo.AccountRole
OriginalL'auteur Jaanus | 2012-12-12
Vous devez vous connecter pour publier un commentaire.
Il suffit de remplacer le
avec:
Et permettent de fusion en cascade:
En raison de fusion fait ceci:
persist()
fera l'objet que vous avez passé une entité gérée, cependant, de fusion sera de retour à une gestion exemplaire de l'objet que vous avez passé. Donc, si vous avez besoin d'une entité gérée après la fusion que vous devriez faireaccount = entityManager.merge(account)
Également prendre un coup d'oeil iciOriginalL'auteur Jaanus
Il semble que vous quittez la transaction au cours de votre traitement, de sorte que le
accountRole
obtient détaché, ou il est déjà détachée pour d'autres raisons.Un appel à
entityManager.merge(accountRole)
avant d'appelerentityManager.persist(account)
devrait résoudre le problème.EDIT: Malheureusement, si vous ne pouvez pas être sûr si les
accountRole
existe déjà dans la base de données, vous devrez le vérifier en interrogeant. Si elle existe - fusion, si ce n'est pas persister. C'est en effet une source de tracas, mais je n'ai pas encore vu une meilleure solution.EDIT2: L'entité que vous passez à la
merge
méthode restera détachée - la gestion de l'entité seront retournés par lamerge
, de sorte que vous devez fusionner tout d'abord, puis définissez la référence sur leaccount
à la valeur de retour de lamerge
.AccountRole
n'existe pas dans la base de données, de sorte que lorsque vous faitesem.persist
, il persiste le compte et accountrole, et tout fonctionne. maintenant, quand je me trouve dans ce cas, avec votre code, c'est d'essayer d'ajouter leAccountRole
deux fois à la base de données, d'abord avec de fusion, avec succeedes et puis avec persistent également, ce qui me donneduplicate key value violation error
, des suggestions? le problème est que, parfois, le rôle n'existe pas.une solution pourrait être que, si
Role
n'existe pas,persist
la fichue chose, mais si le rôle n'existe pas,merge
en premier, mais c'est trop de tracas, n'est-ce pas?hélas, vous avez raison 🙂 j'ai édité la réponse en conséquence.
juste essayé, même chose..
entityManager.merge(account.getAccountRole()); entityManager.persist(account);
et même message d'erreur :detached entity passed to persist: ee.sellin.vahvagame.pojo.AccountRole
.. oh boyil y a une bizarrerie dans l'accord de projet conjoint avec la fusion - j'ai oublié de le préciser, désolé. Voir la deuxième édition.
OriginalL'auteur kostja
Vous ne pouvez pas passer un datached entité à persister, il n'existe aucun moyen. Mais vous n'avez pas besoin d'.
Vous souhaitez conserver un
Account
indépendamment de laAccountRole
(ce qui est déjà persiste). Afin de réaliser cela, il suffit de supprimer en cascade de@ManyToOne
dans l'entité enfant (Account
dans ce cas):Voir mon explication ici, pourquoi: https://stackoverflow.com/a/54271569/522578
OriginalL'auteur Eugen Labun