JCMS et Hibernate

Thomas LEGAT · le 30/10/13 à 15:10

Bonjour,

Dans le cadre d'un projet, nous devons mettre à jour périodiquement des contenus JCMS stockés en base à partir d'une autre table en base. Nous avons donc mis en place un AlarmListener en utilisant la méthode handleTransactionalAlarm étant donné que nous utilisons des contenus stockés en base. 
Nous manipulons pour l'instant environ 17000 objets. Ce chiffre pourra évoluer au cours du temps. Nous avons été confronté dans un 1er temps à un problème de cache de 2nd niveau à travers cette erreur:

 [AbstractReadWriteEhcacheAccessStrategy] - Cache generated.Formation Key generated.Formation#44552 Lockable : nullA soft-locked cache entry was expired by the underlying Ehcache. If this happens regularly you should consider increasing the cache timeouts and/or capacity limits

Ma première question est:
Quelle est la conséquence sur la plateforme de désactiver cette fonctionnalité?

Après avoir désactiver cette option, nous avons alors relancé cette routine et nous avons été confronté à cette erreur:

14:57:05,456 WARN [Portail XXXX] [JDBCExceptionReporter] - SQL Error: 0, SQLState: 08006
14:57:05,456 ERROR [Portail XXXX] [JDBCExceptionReporter] - Une erreur d'entrée/sortie a eu lieu lors d'envoi vers le serveur.
14:57:05,458 ERROR [Portail XXXX] [AbstractFlushingEventListener] - Could not synchronize database state with session
org.hibernate.exception.JDBCConnectionException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:97)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:169)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028)
    at com.jalios.jcms.db.HibernateUtil.delete(HibernateUtil.java:2293)
    at com.jalios.jcms.db.HibernateUtil.delete(HibernateUtil.java:2304)
    at com.jalios.jcms.Channel.deleteData(Channel.java:5384)
    at com.jalios.jcms.Data.performDelete(Data.java:2792)
    at com.jalios.jcms.Publication.performDelete(Publication.java:5899)
    at com.jalios.jcms.Data.performDelete(Data.java:2769)

Y'a t'il une propriété à modifier? Faut il réinitialiser manuellement la session?

Notre contexte: JCMS 7.1.2 en relation avec une base PostgreSQL.

Merci d'avance,

1 pt
Thomas LEGAT · le 31/10/13 à 10:36

Bonjour,

J'ai enfin trouvé une solution à mon problème et je viens la déposer ici.
Il faut donc réinitialiser la session à intervalle régulier pour ne pas tomber dans la fermeture automatique de la session Hibernate.
Le code avant changement était:    

 for (Formation f:collection) {
     if( f.checkDelete(defaultAdmin).isOK() ){
          f.performDelete(defaultAdmin);
       }
   }

Je l'ai changé comme cela:

for (Formation f:collection) {
     if( f.checkDelete(defaultAdmin).isOK() ){
          HibernateUtil.delete(f);
     }
     if( cpt % 1000 == 0 ){
        HibernateUtil.commitTransaction();
        HibernateUtil.closeSession();
        HibernateUtil.beginTransaction();
     }
     cpt++;
}
HibernateUtil.commitTransaction();
HibernateUtil.closeSession();

J'ai donc choisi toutes les 1000 suppressions, de commiter les suppressions et de réiniatialiser la connexion.
J'ai du pour ma part utilisé la méthode: HibernateUtil.delete(DBData) au lieu de DBData.performDelete(Member) car après avoir rouvert la connexion, à la suppression suivante, l'erreur suivante était levée:

org.hibernate.HibernateException: collection is not associated with any session
	org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:471)
	org.hibernate.Hibernate.initialize(Hibernate.java:332)
	com.jalios.jcms.Publication.initializeDBDataCollections(Publication.java:6377)
	generated.Formation.initializeDBDataCollections(Formation.java:488)

Pour information, j'ai aussi au moment de commiter et de réinitialiser la connexion, fais appel à : HibernateUtil.clearCache(); ce qui permets de garder activer le cache de second niveau dans les propriétés du site.

Thomas

4 pts