2016-08-09 73 views
0

Für meine Integrationstests verwende ich einen HSQLDB-Inmemory.Bulkupdate Cache-Problem? Hibernate/IntegrationTest/Inmemory DB/

Wenn ich ein Bulk-Update über JQL-Abfrage ausführen, kann ich die aktualisierten Ergebnisse danach nicht abrufen.

Entity.class

@Entity 
public class Entity { 
    private Long id; 
    private String someCriteria; 
    private Boolean changed = Boolean.FALSE; 

    @Id 
    @Column (name = "ID") 
    public Long getId() { 
     return id; 
    } 

    @Column (name = "SOMECRITERIA") 
    public String getSomeCriteria() { 
     return someCriteria; 
    } 

    @Column (name = "CHANGED") 
    @Type (type = "yes_no") 
    public String isChanged() { 
     return changed; 
    } 

    […] 
} 

DataStore.class [...]

@Transactional 
updateChangedMethod() { 
Query query = entityManager.get().createQuery(“UPDATE Entity e SET e.changed = true WHERE (d.someCriteria = ‘true’) "); 
query.executeUpdate(); 
} 

@Transactional 
selectAllMethod() { 
Query query = entityManager.get().createQuery("Select e from Entity e", Entity.class); 
} 
[…] 

Service.class

execute(){ 
     updateChangedMethod() ; 
     selectAllMethod(); // Results do not contain the update 
    } 

Wenn ich ausführen eine Aktualisierung für jede Entität explizit die Auswahl Werke wie erwartet:

@Transactional 
    refresh(){ 
    Query query = entityManager.get().createQuery("Select e from Entity e", Entity.class); 
    List<Entity> result = query.getResultList(); 

    for (Entity entity : result) { 
     entityManager.get().refresh(entity); 
    } 
    } 


    execute(){ 
      updateChangedMethod() ; 
      refresh(); 
      selectAllMethod(); // Results do contain the update 
     } 

Ich verwende Hibernate v 5.1.0.Final und HSQLDB v 2.3.4. Ich nehme an, dass dies ein Cache-Problem ist, gibt es eine Möglichkeit, die erwarteten Ergebnisse direkt zu erhalten, ohne eine Aktualisierung für jede Entität aufzurufen?

Antwort

1

Der Persistenzkontext wird nicht aktualisiert, um die Ergebnisse der Massenoperation widerzuspiegeln. Massenoperationen werden als SQL für die Datenbank ausgegeben, wobei die speicherinternen Strukturen des Persistenzkontexts umgangen werden.

Sie haben drei Möglichkeiten, die up-to-date Ergebnis von EntityManager zu erreichen:

  • aktualisieren Sie die
  • evict alle Cache in Entity Manager Einheit und es zu zwingen, alles von Anfang an zu aktualisieren
  • Die Bulk-Operationen können in ihren eigenen Transaktionen ausgeführt werden, indem @TransactionAttribute (TransactionAttributeType.REQUIRES_NEW) zur Methodensignatur hinzugefügt wird. (Ich bin nicht sicher, wie es im Frühjahr umgesetzt werden wird, möglicherweise @Transactional (Propagation = Propagation.REQUIRES_NEW))