IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hibernate Java Discussion :

[EhCache] maxElementsInMemory atteint


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 143
    Par défaut [EhCache] maxElementsInMemory atteint
    Bonjour

    J'utilise Spring 2.5.4, Hibernate 3.2.6 et ehcache 1.5.

    Je suis confronté au problème suivant. J'ai configuré, dans la session factory, un objet de domaine pour qu'il soit géré dans le cache de second niveau. Le cache de second niveau est EhCache. Lorsque j'atteins le nombre limite d'éléments dans la région du cache allouée à cet objet de domaine, Hibernate ne va plus chercher les objets dans le cache et lance des requêtes en base de données. Ceci quel que soit l'objet de domaine. J'ai pourtant configuré une stratégie d'éviction LRU (Least Frequently Used) qui est censée retirer du cache seulement l'objet de domaine utilisé le moins récemment.
    Tout ce passe bien tant que je n'ai pas atteint la limite.

    La configuration de ma session factory (avec Spring) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    		<property name="mappingResources">
    			<list>
    				...
    				<value>com/corp/app/domain/hibernate/mapping/livre/TypeOuvrage.hbm.xml</value>
    			</list>
    		</property>
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
    				<prop key="hibernate.hbm2ddl.auto">create</prop>
    				<prop key="hibernate.use_sql_comments">true</prop>
    				<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>
    			</props>
    		</property>
    		<property name="entityCacheStrategies">
    			<props>
    				<prop key="com.corp.app.domain.livre.TypeOuvrage">read-only</prop>
    			</props>
    		</property>
    	</bean>

    La configuration de la région concernée dans ehcache.xml (fichier de conf EhCache) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	<defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskSpoolBufferSizeMB="30"
    		maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />
    
    	<cache name="com.corp.app.domain.livre.TypeOuvrage" maxElementsInMemory="20" eternal="true" timeToLiveSeconds="0" overflowToDisk="false" />
    Mon JUnit qui étend la class Spring AbstractTransactionalSpringContextTests :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
     
    	public void test() {
    		final TypeOuvrage type1 = new TypeOuvrage();
    		type1.setCode("ROMAN");
    		type1.setLibelle("Roman");
     
    		final TypeOuvrage type2 = new TypeOuvrage();
    		type2.setCode("BD");
    		type2.setLibelle("Bande dessinée");
     
    		final TypeOuvrage type3 = new TypeOuvrage();
    		type3.setCode("DICO");
    		type3.setLibelle("Dictionnaire");
     
    		final Session session = super.getSession();
    		session.save(type1);
    		session.save(type2);
    		session.save(type3);
     
    		super.flushAndClearHibernateSession();
     
    		final Statistics statistics = super.sessionFactory.getStatistics();
    		statistics.setStatisticsEnabled(true);
    		statistics.clear();
    		TypeOuvrage t1 = (TypeOuvrage) session.get(TypeOuvrage.class, type1.getId());
    		assertEquals(type1, t1);
    		TypeOuvrage t2 = (TypeOuvrage) session.get(TypeOuvrage.class, type2.getId());
    		assertEquals(type2, t2);
    		TypeOuvrage t3 = (TypeOuvrage) session.get(TypeOuvrage.class, type3.getId());
    		assertEquals(type3, t3);
    		assertEquals(3, statistics.getPrepareStatementCount());
    		assertEquals(3, statistics.getSecondLevelCachePutCount());
    		assertEquals(0, statistics.getSecondLevelCacheHitCount());
    		assertEquals(3, statistics.getSecondLevelCacheMissCount());
     
    		super.flushAndClearHibernateSession();
    		statistics.clear();
     
    		t1 = (TypeOuvrage) session.get(TypeOuvrage.class, type1.getId());
    		assertEquals(type1, t1);
    		t2 = (TypeOuvrage) session.get(TypeOuvrage.class, type2.getId());
    		assertEquals(type2, t2);
    		t3 = (TypeOuvrage) session.get(TypeOuvrage.class, type3.getId());
    		assertEquals(type3, t3);
    		assertEquals(0, statistics.getPrepareStatementCount());
    		assertEquals(0, statistics.getSecondLevelCachePutCount());
    		assertEquals(3, statistics.getSecondLevelCacheHitCount());
    		assertEquals(0, statistics.getSecondLevelCacheMissCount());
    	}
    Explication du test :
    Dans un premier temps, je crée les objets de domaine. Je "flush" et je "clear" la session afin de m'assurer que les objets de domaine ne vont pas être récupérés dans le cache de premier niveau par la suite.
    Ensuite je charge une première fois mes objets de domaine créés précédemment. Vu qu'ils ne sont ni dans le cache de premier niveau (session flushée et clearée), ni dans le cache de second niveau, des requêtes à la base sont lancées. Je m'assure de tout ceci avec des asserts et l'objet Statistics de Hibernate.
    Enfin, dans le dernier bloc de code, je fais exactement pareil, sauf que cette fois ci, aucune requête n'est lancée car les objets ont été "putés" dans le cache de second niveau lors du bloc de code précédent.

    Tout cela marche très bien quand je configure ma région ehcache avec maxElementsInMemory >= "3". Si je mets maxElementsInMemory="2", ça marche plus. Cela est normal car je ne peux avoir que 2 objets de domaine caché. Je devrais donc avoir 1 requête lancée pour accéder à l'objet de domaine qui n'a pas pu être caché car viré du cache pour cause de maxElementInMemory. Or Je n'ai pas une requête qui est lancée mais 3 !

    Pourquoi ?

    Merci d'avance pour votre aide

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 143
    Par défaut
    Ca laisse tout le monde de marbre ?

Discussions similaires

  1. Réponses: 3
    Dernier message: 04/07/2006, 16h35
  2. L'usage du CPU atteint 100% pour une Form
    Par Ben_Le_Cool dans le forum Composants VCL
    Réponses: 14
    Dernier message: 21/09/2005, 11h52
  3. Réponses: 2
    Dernier message: 27/08/2005, 16h12
  4. [FLASH MX2004] Fichier XML hors d'atteinte
    Par ROUMEG dans le forum Flash
    Réponses: 2
    Dernier message: 19/04/2005, 16h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo