2014-12-15 11 views
6

Ich verwende Spring Data JPA mit Hibernate und habe Probleme mit der Eigenschaft update = false auf der @Column Annotation.Hibernate aktualisierbar = falsch UUID Feld ist aktualisiert

Ich habe eine Basisklasse für alle meine @Entity Objekte mit einem UUID wie folgt definiert:

@MappedSuperclass 
@Getter @Setter @EqualsAndHashCode(of= {"uuid"}) 
public abstract class AbstractEntity implements Persistable<Long> { 

    @Id 
    @GeneratedValue(strategy = AUTO) 
    @Column(unique = true, updatable = false) 
    private Long id; 

    @Column(unique = true, updatable = false) 
    private UUID uuid = UUID.randomUUID(); 

} 

Notiere die updatable = false Anmerkung.

Um die UUID-Feld ist in der Tat zu bestätigen nicht aktualisierbar, ich diesen Test geschrieben haben:

@Test 
public void testChangeUUID() { 

    User user = userRepo.findOne(1L); 

    assertNotNull(user); 
    assertEquals(USER_UUID, user.getUuid().toString()); 

    final UUID newUuid = UUID.randomUUID(); 

    user.setUuid(newUuid); 

    user = userRepo.save(user); 

    assertEquals(newUuid, user.getUuid()); 

    User user2 = userRepo.findOne(1L); 
    assertNotNull(user2); 
    assertEquals("UUID should not have changed", USER_UUID, user2.getUuid().toString()); 
} 

Ich war eigentlich eine Ausnahme erwartet auf den Anruf zu userRepo.save(user) geworfen werden, aber das geschieht nicht. Stattdessen schlägt die letzte assertEquals() fehl, was bedeutet, dass die UUID tatsächlich aktualisiert wurde.

Ist das erwartete Verhalten? Gibt es eine Möglichkeit zu verhindern, dass UUIDs geändert werden?

+0

Aufruf Es wird nicht aktualisiert, Ihr Test fehlerhaft ist. Es gibt keine Ausnahme, das Feld wird beim Speichern/Aktualisieren des Objekts stillschweigend ignoriert. In der Datenbank hat sich nichts geändert. Das Problem mit Ihrem Test ist, dass alles in einer einzigen Transaktion und somit in einem einzigen Cache der ersten Ebene (d. H. Dem "EntityManager") geschieht. Das 'user'- und' user2'-Objekt ist das gleiche Objekt ('user == user2' sollte' true' zurückgeben). Ihre letzte Assertion ist falsch, da Sie die In-Memory-Darstellung des Objekts 'Benutzer' geändert haben. Nicht die Datenbank. Sie möchten eine einfache Abfrage verwenden, um dies zu testen. –

Antwort

5

Wie in der documentation, die updatable Eigenschaft entschieden, ob die Spalte Teil der Update-Anweisung sein würde. Dies bedeutet, dass Hibernate dies ignoriert, wenn Updates an die Datenbank gesendet werden. Daher unterscheiden sich der speicherinterne Zustand und der Datenbankstatus.

Um dies zu überprüfen, versuchen Sie die Sitzung Clearing (evict) vor User user2 = userRepo.findOne(1L)

+0

Ich kannte den ersten Teil, wusste aber nicht, dass Hibernate das Objekt zwischenspeichert. Ich habe 'entityManager.clear();' vor dem 'findOne() 'in meinem Test hinzugefügt und jetzt wird es genau übergeben. Danke, dass Sie das Recht direkt angegeben haben. – JBCP

Verwandte Themen