2011-06-23 2 views
0

je les 2 Hibernate ENTITES suivantes:problèmes de mise en cache de collecte Hibernate

@Entity 
@Table(name = "VEHICLE_BRAND") 
public class VehicleBrand implements java.io.Serializable { 

    ... 

    @Column(name = "NAME", nullable = false, length = 1000) 
    public String getName() { 
    return name; 
    } 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "vehiclebrand") 
    public Set<VehicleModel> getVehicleModels() { 
    return vehicleModels; 
    } 

    ... 

} 

et

@Entity 
@Table(name = "VEHICLE_MODEL") 
public class VehicleModel implements java.io.Serializable { 

    ... 

    @Column(name = "NAME", nullable = false, length = 1000) 
    public String getName() { 
    return name; 
    } 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="VECHILE_BRAND_ID") 
    public VehicleBrand getVehicleBrand() { 
    return this.vehicleBrand; 
    } 

    ... 

} 

Et je le test unitaire suivant qui teste VehicleBrand et VehicleModel:

DefaultTransactionDefinition txDef = new DefaultTransactionDefinition(); 
txDef.setName("test1"); 
txDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 
TransactionStatus txStatus = txManager.getTransaction(txDef); 

// Load brand "1" object. 
VehicleBrand brand = (VehicleBrand) factory.getVehicleBrandDAO().findFirstByName("1"); 
assertNotNull(brand); 

// Check if model "X" exists for brand "1" through collection. 
Set<VehicleModel> models = brand.getVehicleModels(); 
for (final VehicleModel model : models) { 
    assertFalse(model.getName().equals("X")); 
} 

// Add model "X" to brand "1". 
VehicleModel model = new VehicleModel(); 
model.setName("X"); 
model.setValidFrom(new Date()); 
model.setVehicleBrand(brand); 
factory.getVehicleModelDAO().create(model); 

txManager.commit(txStatus); 

txDef = new DefaultTransactionDefinition(); 
txDef.setName("test2"); 
txDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 
txStatus = txManager.getTransaction(txDef); 

// Check that model is added to database. 
model = (VehicleModel) factory.getVehicleModelDAO().findFirstByName("X"); 
assertNotNull(model); 
assertEquals(model.getVehicleBrandId().longValue(), 1L); 

// Check if model X exists for brand "1" through collection. 
brand = (VehicleBrand) factory.getVehicleBrandDAO().findFirstByName("1"); 
models = brand.getVehicleModels(); 
boolean found = false; 
for (final VehicleModel model2 : models) { 
    if (model2.getName().equals("X")) { 
    found = true; 
    } 
} 
assertTrue(found); 

txManager.commit(txStatus); 

Quelqu'un peut-il m'expliquer pourquoi la dernière ligne échoue?

+0

Pouvez-vous mettre à jour le code avec les extraits de 'getNavn' ou le membre associé qui serait stocké dans la base de données? –

+0

Désolé, c'était une faute de frappe, ça s'appelle getName et j'ai ajouté des définitions de getter/annotation à l'entité dans la question –

+0

J'ai mis à jour le cas de test pour m'assurer qu'une nouvelle transaction est démarrée entre les demandes –

Répondre

1

Il échoue certainement parce que vous exécutez tout cela dans la même transaction, et donc la même instance VehicleBrand est toujours retournée à partir du cache de session. Puisque vous avez oublié de conserver les deux côtés de l'association lorsque vous avez créé votre VehicleModel (vous avez attribué la marque au nouveau modèle, mais avez oublié d'ajouter le modèle créé à la collection de modèles de la marque), les mêmes modèles est toujours renvoyé et ne contient pas le nouveau modèle créé.

+0

1) Les demandes de recherche sont exécutées dans différentes sessions d'hibernation, 2) Je peux aussi voir dans les logs que sur chaque findFirstByName il y a une requête SQL exécutée sur la base de données –

+0

Avez-vous vérifié que le modèle en effet écrit en base de données à la fin de votre première transaction, et que son nom et son identifiant sont corrects (puisque la transaction est validée, vous devriez pouvoir la voir dans la base de données)? –

Questions connexes