Bonjour,
je travaille sur une application développée en JAVA JEE avec les frameworks Spring, Hibernate et JPA. Cette application est multi-utilisateurs.
Mon problème est le suivant :
lorsqu'un utilisateur enregistre une donnée, celle-ci se persiste bien dans la base de données mais elle n'est pas visible des autres utilisateurs de l'application tant que le serveur TOMCAT n'est pas redémarré. Si je redémarre le serveur, les données sont visibles pas tous les utilisateurs.
Je me suis donc dit qu'il s'agissait d'un problème lié au niveau du cache d'hibernate :
Le premier niveau de cache est spécifique à une session, il n'est donc pas partagé et est activé par défaut.
Le second niveau de cache lui est partagé par toutes les sessions, mais il n'est pas activé par défaut.
J'ai donc étudié la question sur différents forums et j'ai modifié mon application de la manière suivante :
voici mon fichier persistence.xml :
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 <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="Zeilt-ProductionsPU" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <non-jta-data-source>zeilt</non-jta-data-source> <properties> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.cache.use_second_level_cache" value="true"/> <property name="hibernate.cache.use_query_cache" value="true"/> <property name="hibernate.cache.use_minimal_puts" value="true"/> <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/> <property name="hibernate.cache.provider_configuration_file_resource_path" value="META-INF/ehcache.xml"/> </properties> </persistence-unit> <persistence-unit name="TestPersistenceUnit"> <description>TestPersistenceUnit</description> <provider>org.hibernate.ejb.HibernatePersistence</provider> </persistence-unit> </persistence>
voici mon fichier applicationContext.xml :
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans <a href="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" target="_blank">http://www.springframework.org/schem...-beans-2.5.xsd</a> <a href="http://www.springframework.org/schema/aop" target="_blank">http://www.springframework.org/schema/aop</a> <a href="http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" target="_blank">http://www.springframework.org/schem...ng-aop-2.5.xsd</a> <a href="http://www.springframework.org/schema/tx" target="_blank">http://www.springframework.org/schema/tx</a> <a href="http://www.springframework.org/schema/tx/spring-tx-2.5.xsd" target="_blank">http://www.springframework.org/schem...ing-tx-2.5.xsd</a> <a href="http://www.springframework.org/schema/context" target="_blank">http://www.springframework.org/schema/context</a> http://www.springframework.org/schema/context/spring-context-2.5.xsd" > <!-- Active la prise en charge par Spring de diverses annotations. --> <context:annotation-config /> <!-- Active le scan par Spring des beans pour diverses annotations. On spécifie le package de base où effectuer le scan. --> <context:component-scan base-package="com.zeilt.production" /> <!-- Lecture des propriétés de configuration --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" p:location="/WEB-INF/jdbc.properties" /> <!-- Source de données --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}" /> <!-- Gestion des messages internationalisés --> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename"> <value>/WEB-INF/i18n/messages</value> </property> <property name="defaultEncoding" value="UTF-8" /> <property name="cacheSeconds" value="1" /> <property name="fallbackToSystemLocale" value="false" /> </bean> <!-- EntityManagerFactory --> <!-- Configuration de la factory et association de la source de données LocalContainerEntityManagerFactoryBean--> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="Zeilt-ProductionsPU" /> <property name="dataSource" ref="dataSource" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect"/> </bean> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> <property name="dataSource" ref="dataSource" /> </bean> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" /> <bean id="cacheProvider" class="org.springmodules.cache.provider.ehcache.EhCacheFacade"> <property name="cacheManager" ref="cacheManager" /> </bean> </beans>
voici mon fichier ehcache.xml :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 <ehcache> <diskStore path="java.io.tmpdir"/> <cache name="org.test.MYCACHE" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="0" timeToLiveSeconds="5000" overflowToDisk="true" /> </ehcache>
lorsque je déploie mon application, voici les traces que je récupère à propos du cache :
11 avr. 2010 17:47:00 org.hibernate.cfg.SettingsFactory buildSettings
INFO: Second-level cache: enabled
11 avr. 2010 17:47:00 org.hibernate.cfg.SettingsFactory buildSettings
INFO: Query cache: enabled
11 avr. 2010 17:47:00 org.hibernate.cfg.SettingsFactory createCacheProvider
INFO: Cache provider: org.hibernate.cache.EhCacheProvider
11 avr. 2010 17:47:00 org.hibernate.cfg.SettingsFactory buildSettings
INFO: Optimize cache for minimal puts: enabled
11 avr. 2010 17:47:00 org.hibernate.cfg.SettingsFactory buildSettings
INFO: Structured second-level cache entries: disabled
11 avr. 2010 17:47:00 org.hibernate.cfg.SettingsFactory createQueryCacheFactory
INFO: Query cache factory: org.hibernate.cache.StandardQueryCacheFactory
11 avr. 2010 17:47:00 org.hibernate.cfg.SettingsFactory buildSettings
d'après ce que je comprends, le cache de second niveau est activé.
J'ai également rajouté l'annotation @cache suivante sur toutes mes entités hibernates :
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
Pourtant, lorsq'un user enregistre un message sur l'application celle-ci n'est pas mise à jour tant que le serveur n'est pas redémarré pour recharger le cache.
Est ce que quelqu'un pourrait m'aiguiller sur ce petit mystère ?
Partager