Rss Feed

Apache CXF et Hibernate hbm2java

L’utilisation de Apache CXF/JAX-RS pour la création de services REST passe par l’ajout d’annotations dans vos POJOs ce qui peut être contraignant quand ceux-ci sont générés depuis vos fichiers hbm via hbm2java. Heureusement il existe une solution à ce problème via l’utilisation de freemarker. Freemarker est une librairie de génération de template utilisée par hbm2java pour transformer les xml de mapping (.hbm) en POJOs java. Prenons par exemple l’annotation @XmlRootElement qui doit précéder tous les pojos que jax-rs va transformer en XML :

Dans votre target ANT hbm2java ajouter templatepath=“resources/META-INF/pojo_templates/“ avec pojo_templates le répertoire qui contiendra les templates freemarker modifiées.

Dans  resources/META-INF/pojo_templates/ créer un fichier ‘PojoTypeDeclaration.ftl’ avec le contenu suivant :

<#if pojo.hasMetaAttribute("xmlrootelement")>

import javax.xml.bind.annotation.XmlRootElement;

</#if>

/**

${pojo.getClassJavaDoc(pojo.getDeclarationName() + " generated by hbm2java", 0)}

*/

<#include "Ejb3TypeDeclaration.ftl"/>

<#if pojo.hasMetaAttribute("xmlrootelement")>

@XmlRootElement(name="${pojo.getMetaAsString("xmlrootelement")}")

</#if>

${pojo.getClassModifiers()} ${pojo.getDeclarationType()} ${pojo.getDeclarationName()} ${pojo.getExtendsDeclaration()} ${pojo.getImplementsDeclaration()}

Il suffit alors d’ajouter dans votre fichier .hbm un meta attribute indiquant le nom du POJO. Exemple :

<hibernate-mapping package=“com.pojos”>

<class name=“MaClass” table=“ma”_table>

<meta attribute="xmlrootelement">MaClass</meta>

...

Le POJO généré sera alors de la forme :

import javax.xml.bind.annotation.XmlRootElement;

/**

* MaClass generated by hbm2java

*/

@XmlRootElement(name=“MaClass”)

public class MaClass  implements java.io.Serializable { ... }


On peut biensur appliquer ce principe à d’autres annotations (XmlSeeAlso …) et à d’autres frameworks.

Apache Cassandra

Dans le cadre d’un projet interne R&D nous avions besoin d’un système permettant de stocker un nombre très important de données tout en conservant des temps d’accès très court pour les recherches. Après plusieurs essais, il était évident qu’une base de donnée relationnelle standard comme MySQL ne pouvait répondre à notre besoin : même avec un bon choix d’index les ressources matérielles demandées pour gérer des tables contenant des centaines de millions d’enregistrement étaient trop importantes.

Nous nous sommes donc tournés vers Apache Cassandra à l’origine développé par Facebook derrière un index lucene.

Architecture de la base Apache Cassandra :

- un keyspace dans cassandra contient un ensemble non fini de lignes

- chaque ligne posséde 2 familles de colonnes

- chaque famille de colonne possède un ensemble non fini de super colonnes (en moyenne 30 000 super colonnes)

- chaque super colonne possède un ensemble non fini de colonnes (en moyenne une cinquantaine)

- chaque ligne possède un index Lucene qui lui est propre

- chaque valeur de colonne est indexée dans Apache Lucene

En ne comptant qu’une seule famille de colonne et une centaine de lignes on arrive déjà à 150 000 000 de cellules.

Cassandra étant un système NoSQL, il n’est pas possible de faire des requêtes complexes sur les valeurs stockées et ce n’est d’ailleurs pas le but. Grâce à la conjonction de Lucene et d’une API JAVA complète que nous avons développé en interne cela devient un non problème, Lucene offrant des fonctions très pratiques telles que le must/should, le classement par pertinence.

Les tests effectués révèlent des temps d’accès aux données très rapides (de quelques millisecondes) malgré le quantité, là où MySQL Cluster mettait plusieurs secondes.