2014-03-27 10 views
13

Ich habe eine Feder 4 App, wo ich versuche, eine Instanz einer Entität aus meiner Datenbank zu löschen. Ich habe die folgende Einheit:Löschen funktioniert nicht mit JpaRepository

@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 
} 

Ich habe eine JpaRepository Schnittstelle definiert:

public interface TokenRepository extends JpaRepository<Token, Long> { 

    Token findByValue(@Param("value") String value); 

} 

ich einen Unit-Test-Setup haben, die mit einer In-Memory-Datenbank (H2) arbeitet, und ich bin vor dem Befüllen des Datenbank mit zwei Tokens:

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

Die erste Behauptung passiert, die zweite fehlschlägt. Ich habe einen anderen Test ausprobiert, der den Token-Wert ändert und in der Datenbank speichert, und es funktioniert tatsächlich, daher bin ich mir nicht sicher, warum das Löschen nicht funktioniert. Es werden auch keine Ausnahmen ausgelöst, sondern nur die Datenbank. Es funktioniert auch nicht gegen meine Oracle-Datenbank.


bearbeiten

Immer noch dieses Problem. Ich konnte das Löschen erhalten, indem das Hinzufügen dieser zu meiner TokenRepository Schnittstelle zur Datenbank beharren:

@Modifying 
@Query("delete from Token t where t.id = ?1") 
void delete(Long entityId); 

aber dies keine ideale Lösung ist. Irgendwelche Ideen, was ich tun muss, damit es ohne diese zusätzliche Methode funktioniert?

Antwort

1

Ihr Anfangswert für id ist 500. Das heißt, Ihre ID beginnt mit 500

@SequenceGenerator(name = "seqToken", sequenceName = "SEQ_TOKEN", 
initialValue = 500, allocationSize = 1) 

Und Sie wählen ein Element mit der ID 1 hier

Token deleted = tokenRepository.findOne(1L); 

So Ihre Datenbank überprüfen, ob zu klären

+0

Ich glaube nicht, dass das Problem hier ist, weil, wenn ich den Test mit Testdaten Saatgut ich die Angabe der ID 1. –

11

Ich hatte das gleiche Problem

Vielleicht hat Ihre UserAccount-Entity eine @OneToMany mit Cascade für ein Attribut.

Ich habe gerade die Kaskade entfernen, als es anhalten könnte beim Löschen ...

+0

Das funktionierte auch für mich zu sein. Insbesondere habe ich herumgespielt und war in der Lage, diese Kaskadentypen zu behalten: [CascadeType.PERSIST, CascadeType.REFRESH] und bekomme immer noch das Löschen, um durch das Kind-Repository zu arbeiten. Was für mich keinen Sinn ergab, war, dass ich die Eigentümer-Entität über "mappedBy" auf dem Elternknoten zum Kind gemacht habe. – GameSalutes

+0

Diese Lösung scheint zu funktionieren, gibt aber keine Erklärung. –

2

Ich ging gerade durch diese auch. In meinem Fall musste ich dafür sorgen, dass die untergeordnete Tabelle ein Nullable-Feld für den Fremdschlüssel enthält, und dann den Elternknoten aus der Beziehung entfernen, indem ich null anwendete und dann save und delete und flush aufruft.

Ich habe keine Löschung im Protokoll oder eine Ausnahme vor dem Ausführen dieses Vorgangs angezeigt.

+0

Ich hatte das gleiche Problem und stieß auf diesen Thread. Ich weiß nicht, ob ich dies eine Lösung oder einen Workaround nennen würde, aber so können die untergeordneten Objekte gelöscht werden. –

2

Wenn Sie eine neuere Version von Spring Data verwenden, können Sie deleteBy Syntax verwenden ... so Sie in der Lage sind eine Ihrer Anmerkungen zu entfernen: P

die nächste Sache ist, dass das Verhalten bereits Darm-Trakt ist durch ein Jira Ticket: https://jira.spring.io/browse/DATAJPA-727

1

Sie benötigen preremove Funktion, in der Klasse hinzuzufügen, wo Du viele Objekt als Attribut zum Beispiel in Bildung Klasse haben, die Beziehung mit Userprofile Bildung haben.

java
private Set<UserProfile> userProfiles = new HashSet<UserProfile>(0); 

@ManyToMany(fetch = FetchType.EAGER, mappedBy = "educations") 
public Set<UserProfile> getUserProfiles() { 
    return this.userProfiles; 
} 

@PreRemove 
private void removeEducationFromUsersProfile() { 
    for (UsersProfile u : usersProfiles) { 
     u.getEducationses().remove(this); 
    } 
} 
Verwandte Themen