Supprimer ne fonctionne Pas avec JpaRepository
J'ai un ressort 4 app lorsque j'essaie de supprimer une instance d'une entité à partir de ma base de données. J'ai l'entité suivante:
@Entity
public class Token implements Serializable {
@Id
@SequenceGenerator(name = "seqToken", sequenceName = "SEQ_TOKEN", initialValue = 500, allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqToken")
@Column(name = "TOKEN_ID", nullable = false, precision = 19, scale = 0)
private Long id;
@NotNull
@Column(name = "VALUE", unique = true)
private String value;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "USER_ACCOUNT_ID", nullable = false)
private UserAccount userAccount;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "EXPIRES", length = 11)
private Date expires;
...
//getters and setters omitted to keep it simple
}
J'ai un JpaRepository interface définie:
public interface TokenRepository extends JpaRepository<Token, Long> {
Token findByValue(@Param("value") String value);
}
J'ai une unité de configuration de test qui fonctionne avec une mémoire de base de données (H2) et je suis pré-remplissage de la base de données avec deux jetons:
@Test
public void testDeleteToken() {
assertThat(tokenRepository.findAll().size(), is(2));
Token deleted = tokenRepository.findOne(1L);
tokenRepository.delete(deleted);
tokenRepository.flush();
assertThat(tokenRepository.findAll().size(), is(1));
}
La première affirmation qui passe, la seconde échoue. J'ai essayé un autre test qui change la valeur du jeton et l'enregistre dans la base de données et il fonctionne, donc je ne suis pas sûr de savoir pourquoi les supprimer ne fonctionne pas. Il ne jette pas des exceptions soit, juste ne pas persister dans la base de données. Il ne fonctionne pas à l'encontre de ma base de données oracle.
Modifier
Toujours avoir ce problème. J'ai été en mesure d'obtenir la suppression de persister à la base de données en ajoutant ceci à mon TokenRepository interface:
@Modifying
@Query("delete from Token t where t.id = ?1")
void delete(Long entityId);
Cependant, ce n'est pas une solution idéale. Toutes les idées de ce que je dois faire pour le faire fonctionner sans cette méthode supplémentaire?
Malheureusement pas. Je n'ai plus eu besoin de le faire ici plus et les autres endroits que j'avais à faire, il semblait aller bien. Je ne sais pas ce qui était si spécial au sujet de cette affaire.
OriginalL'auteur Twisty McGee | 2014-03-27
Vous devez vous connecter pour publier un commentaire.
J'ai eu le même problème
Peut-être votre Compteutilisateur entité a un @OneToMany avec Cascade sur un attribut.
Je viens de supprimer la cascade, qu'il ne pouvait persister lors de la suppression d'...
Cette solution semble fonctionner mais ne donne aucune explication .
OriginalL'auteur Davi Arimateia
Vous devez ajouter PreRemove fonction ,dans la classe où vous avez beaucoup d'objets comme attribut de l'e.g dans l'Éducation de la Classe qui ont un lien avec UserProfile
Education.java
OriginalL'auteur Taimur
Plus, probablement, un tel comportement se produit lorsque vous avez relation bidirectionnelle et vous n'êtes pas la synchronisation des deux côtés TOUT en ayant à la fois le parent et l'enfant ont persisté (attaché à la session en cours).
C'est délicat et je vais expliquer cela avec l'exemple suivant.
Écrivons un test (une transactionnel btw)
Assez simple test à droite? Nous sommes en train de créer le parent et l'enfant, l'enregistrer dans la base de données, puis aller chercher un enfant à partir de la base de données, de les enlever et enfin de vérifier que tout fonctionne comme prévu. Et il n'est pas.
Le supprimer ici n'a pas fonctionné parce que nous n'avons pas synchronisé l'autre partie de la relation qui est conservé DANS la SESSION en cours. Si le Parent n'était pas associé à la session actuelle de notre test pass, c'est à dire
et
Bien sûr, il ne prouve mon point de vue et explique le comportement OP face. La bonne chose à faire est évidemment de garder en synchronisation les deux parties de la relation qui signifie:
Évidemment @PreRemove pourrait être utilisé ici.
OriginalL'auteur pzeszko
Je suis juste allé à travers ce aussi. Dans mon cas, j'ai dû faire de l'enfant tableau nullable champ de clé étrangère, puis de supprimer le parent à partir de la relation par le paramètre null, puis de l'appel d'enregistrer et de supprimer et de chasse.
Je n'ai pas vu de supprimer dans le journal ou toute exception avant de le faire.
OriginalL'auteur Lucas Holt
Si vous utilisez une version plus récente de Printemps de Données, vous pouvez utiliser deleteBy syntaxe...donc vous êtes en mesure de supprimer l'un de vos annotations 😛
la prochaine chose est que le comportement est déjà voies par un ticket Jira:
https://jira.spring.io/browse/DATAJPA-727
OriginalL'auteur Eruvanos
Valeur initiale pour l'id est de 500. Cela signifie que votre id commence avec 500
Et vous sélectionnez un élément avec l'id 1 ici
Afin de vérifier votre base de données afin de préciser que
OriginalL'auteur Bitman
Une façon est d'utiliser
cascade = CascadeType.ALL
comme ceci dans votre compteutilisateur service:De faire quelque chose comme ce qui suit (ou similaire logique)
Avis de la
@Transactional
annotation. Cela permettra de Printemps (Hibernate) pour savoir si vous souhaitez persist, merge, ou peu importe ce que vous faites dans la méthode. Autant que je sache, l'exemple ci-dessus devrait travail comme si vous n'aviez pas de CascadeType ensemble, et de l'appelJPARepository.delete(token)
.OriginalL'auteur venge