vendredi 18 septembre 2009

Echapper une chaine en Unicode en Java

Bonjour,
voici une petite source pour vous aider à convertir une chaine de caractère en son équivalent unicode échappé (par exemple \u0025 pour le caractère pourcent).

J'en ai eu besoin dans un projet où il y avait des problèmes d'encodage : ma chaine en dur dans le code, passait bien sur ma machine, mais lorsque le code était compilé sur une autre machine, les caractères accentués de ma chaine ne passaient pas bien (pb d'encodage de mon fichier) et provoqué des bugs.
Pour éviter tout souci avec les caractères accentués, j'ai remplacé tout mes accents par leur équivalent unicode donc il n'y aura plus de pb à la compilation sur n'importe quel systeme (UNIX ou Windaube par exemple).

Voici la fonction :

public static String escapeUnicode(String s)
{
// utiliser un string builder et non pas une string pour des raisons de
// performances
StringBuilder sb = new StringBuilder(s.length() * 6);

// converti caractere par caractere
for (int i = 0; i < s.length(); i++)
{
// fait la convertion :
// prends le code ascii en hexadécimal sur 4 caracteres (par exemple
// 0025 pour le %)
// et rajoute \\u devant
sb.append(String.format("\\u%04x", (int) s.charAt(i)));
}

// renvoi le résultat
return sb.toString();
}


Un exemple :
la chaine : c'est l'été
donne : \u0063\u0027\u0065\u0073\u0074\u0020\u006c\u0027\u00e9\u0074\u00e9

dimanche 30 août 2009

Overflow sur une table qui marche sous IE

Bonjour,
je voulais faire un truc tout simple en HTML : une table avec une scrollbar verticale permettant de faire défiler le contenu tout en gardant les titres des colonnes en haut de la table. Très simple pour FF : 5 min suffisent ! Par contre, comme toujours, là où ça se gatte, c'est avec IE !

Version FF :
Cette table fonctionne parfaitement sous FF : il suffit de rajouter le style overflow: auto; height: 200px; sur le tbody de la table.
Colonne 1Colonne 2Colonne 3Colonne 4
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234


Bien sur avec IE, ça fonctionne pas ! Donc il faut bidouiller un peu :
il faut d'abord une table qui contiendra les titres des colonnes, puis un div contenant une autre table contenant les données. Le overflow sera positionné sur le div uniquement.
En gros :

<table id="tableTitres" style="width:400px">
<thead>
<tr>
<th id="tcol1" style="width:25%">Colonne 1</th>
<th id="tcol2" style="width:25%">Colonne 2</th>
<th id="tcol3" style="width:25%">Colonne 3</th>
<th id="tcol4" style="width:25%">Colonne 4</th>
</tr>
</thead>
</table>

<div id="divContenu" style="height:200px;overflow:auto;width:417px">
<table id="tableContenu" style="width:400px">
<tbody>
<tr>
<td id="ccol1" style="width:25%">1</td>
<td id="ccol2" style="width:25%">2</td>
<td id="ccol3" style="width:25%">3</td>
<td id="ccol4" style="width:25%">4</td>
</tr>
</tbody>
</table>
</div>

Notez : la table du contenu et des titres doivent avoir la même largeur (ici 400px), le div du contenu doit être légèrement plus large (ici 417px) pour avoir la scrollbar sur la droite en dehors de la table
De plus, pour que les titres et les données s'affichent bien en face, on est obligé de préciser les largeurs des colonnes pour qu'elles coïncident.

Ce qui donne :
Colonne 1Colonne 2Colonne 3Colonne 4
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234


Comme vous le constatez, comme les données et les titres ne sont pas dans la même table, les colonnes n'ont pas la même largeur. On peut y remédier en spécifiant les largeurs manuellement : rajouter le style width sur les titres et sur les colonnes :
Colonne 1Colonne 2Colonne 3Colonne 4
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234


Le principal défaut de cette solution est qu'il faut préciser explicitement les largeurs des colonnes. Avec du javascript, on peut faire très facilement un patch qui met automatiquement la largeur des colonnes :

var nbc=4; //nb de colonnes

//table des titres
var tableTitre=document.getElementById('tableTitres');

//table du contenu
var divContenu=document.getElementById('divContenu');

//table du contenu
var tableContenu=document.getElementById('tableContenu');

//largeur de la table des titres
var w=tableTitre.clientWidth;

//regle la largeur du div et de la
//table contenu pour que la scrollbar
//soit en dehors de la table
divContenu.style.width=w+"px";
tableTitres.style.width=w-17;
tableContenu.style.width=w-17;

//regle les largeurs des colonnes
//de la table contenu pour avoir
//exactement les mêmes largeurs
//que les colonnes titres
for(var i=1;i<=nbc;i++) {
var tcolw=document.getElementById('tcol'+i).clientWidth;

var ccol=document.getElementById('ccol'+i);

ccol.width=tcolw;

}

mercredi 5 août 2009

Bug WebSphere avec Struts 2

Bonjour,
j'ai eu un bug en utilisant l'annotation CustomValidator en Struts 2. En effet, quand je passais des paramètres à cette annotations (parameters), la classe plantait à l'éxécution sur le serveur websphere 6.1 :
Caused by: java.lang.ArrayStoreException
at com.ibm.oti.reflect.AnnotationHelper.getReturnValueFromEntry(Native Method)
at com.ibm.oti.reflect.AnnotationHelper.access$000(AnnotationHelper.java:14)
at com.ibm.oti.reflect.AnnotationHelper$AnnotationInvocationHandler.invoke(AnnotationHelper.java:104)

Après avoir retourné la doc Struts 2 dans tous les sens pendant deux heures, en voyant le com.ibm.oti.reflect dans la trace, ça m'a mit la puce à l'oreille : et si c'était pas un bug de la JVM de WebSphere ? (je rappelle WebSphere utilise une JVM IBM et non pas Sun d'où parfois des comportements différents entre les deux implèmentations).

Bingo ! c'est bien un bug de la JVM d'IBM. Y remedier ? pas de soucis, il suffit de télécharger le Java SDK 1.5 SR9 Cumulative pack (le 9 est le dernier en date, 03/03/2009) téléchargeable à l'adresse suivante :
Pour le SDK 1.5 SR9 : http://www-01.ibm.com/support/docview.wss?rs=180&uid=swg24022256

J'ai mis à jour mon WebSphere : magique tout fonctionne à présent ! :)

mardi 30 juin 2009

Publier un EAR sur un WebSphere distant avec Maven 2

Voici comment publier un EAR créé avec RAD par exemple sur un serveur WebSphere 6 installé sur une autre machine avec le plugin Was6 Maven Plugin.

Les informations sur le site du plugin n'étant pas très nombreuses, je trouve bon de présenter rapidement ici un cas concret pour son utilisation !

Il faut que le serveur WebSphere sur la machine distant soit démarré. ET, je le précise car c'est pas clair sur le site du plugin, il FAUT qu'un WebSphere soit installé sur le poste à partir duquel on envoi le EAR. Il ne faut pas qu'il soit démarré. En effet, le plugin a besoin de scripts pour le déploiement du EAR d'où la nécessité d'une installation de WS.

Après avoir généré l'EAR, il suffit simplement de taper la commande Maven 2 dans son projet Web :
mvn was6:installApp
-Dwas6.host=MON_SRV
-Dwas6.conntype=SOAP
-Dwas6.username=MON_USR
-Dwas6.password=MON_PSW
-Dwas6.updateExisting=false
-Dwas6.earFile=monProjet-web.ear
-Dwas6.port=8880
(les retours à la lignes sont là par soucis
de lisibilité)

Il faut remplacer :
MON_SRV par le nom ou l'adresse du serveur distant où déployer l'EAR sur le WebSphere
MON_USR et MON_PSW sont utilisés si la sécurité est activé sur le WebSphere distant (sinon ne pas renseigner ces valeurs)
updateExisting : si l'application a deja été déployée une fois, mettre à true pour qu'on fasse un update
earFile : le chemin vers l'EAR à déployer

C'est donc tout simple !

NOTE méga importante : j'ai remarqué que le déploiement ne fonctionne pas si le chemin vers votre projet Web contient des espaces (erreur lors du build avec ant) ! Déplacer éventuellement le projet pour que son chemin n'en contienne pas ! je vous aurez prévenu ! :)

Néanmoins, si comme moi, vous avez activé la sécurité SSL sur votre serveur WebSphere, il FAUT le certificat de sécurité du serveur pour que la commande fonctionne !

Voici comment procéder (inspiré de la doc d'IBM : http://publib.boulder.ibm.com/infocenter/iwphelp/v2r5m1/index.jsp?topic=/com.ibm.wcs.ic.doc_2.5.1/infocenter/i_sec_t_impcertwasstores.html) : il faut exporter le certificat de sécurité SSL depuis le serveur distant et l'installer dans le WebSphere de la machine à partir de laquelle est déployée l'application.

Exporter le certificat :
1. Ouvrir la console administrative du serveur WebSphere distant
2. Aller dans Sécurité/Certificat SSL et gestion des clés
3. Cliquer sur 'Gérer les configurations de sécurité du noeud final'
4. Déplier 'Communication entrante/...Cell/nodes/servers/server1/ (varie selon le serveur)
5. Cliquer sur 'SOAP_CONNECTOR_ADDRESS'
6. Dans l'écran, cliquer sur 'Gérer des certificats'
7. Cocher dans la liste des certificats, le certificat concerné (en général Default) puis cliquer sur Extraire
8. Dans l'écran d'extraction, saisir un nom (par ex monCertificat.cer) et sélectionner 'Données ASCII codées en base 64' pour le type de données
9. Cliquer sur Ok, le certificat est extrait
10.Récupérer le fichier du certificat en allant dans le profil du WebSphere, par exemple dans C:\Program Files\IBM\SDP70\runtimes\base_v61\profiles\AppSrv01\etc

Importer le certificat sur la machine à partir de laquelle est déployée l'application :
1. Aller dans le répertoire du profil WebSphere de la machine à partir de laquelle est déployée l'application (par exemple dans C:\Program Files\IBM\SDP70\runtimes\base_v61\profiles\AppSrv01)
2. Exécuter le fichier bat ikeyman.bat se situant dans bin/
3. Le gestionnaire des clés IBM s'ouvre
4. Cliquer sur ouvrir un fichier : pour le type de base de données de clés, sélectionner PKCS12.
5. Ouvrir le fichier trust.p12 du répertoire etc/ du profil (par exemple dans C:\Program Files\IBM\SDP70\runtimes\base_v61\profiles\AppSrv01\etc\)
6. Si on vous demande un mot de passe, le mot de passe par défaut est WebAS
7. Une fois chargé, cliquer sur Ajout
8. Sélectionner le certificat récupéré du serveur distant (voir plus haut)
9. Une fois ajouté, sauvegarder en écrasant le fichier trust.p12 ouvert plus haut (mettre le même mot de passe)
10. Vous pouvez quitter ikeyman

La commande Maven 2 devrait désormais fonctionner !

Voili, c'est tout !

jeudi 18 juin 2009

Utiliser les Advanced Queue en Java sur Oracle !

Après 3 jours de nuits blanches à chercher sur des milliers de sites pour intégrer les queues et JMS (Java Message Service) sur mon serveur Oracle 9i, j'ai enfin réussi à faire ce que je voulais... ouf! :)

Voici ce que je cherche à faire :
J'ai une base Oracle 9i, lorsqu'un enregistrement dans une table (par exemple la table Banque) est modifié/créé, je veux que mon application Java soit directement mise au courant lorsque l'opération est effectuée sur la base de données.

Pour "mettre au courant" mon application, on utilise un service très pratique introduit dans J2EE : JMS (Java Message Service). Comme son nom l'indique, c'est un service de message. Les messages sont produits dans une Queue et lus par les destinataires à partir de celle çi.

La base Oracle, à la modification/création d'un élément de la table Banque, produira un message JMS qui sera capté par mon application Java. Oui vous avez bien lus : Oracle est capable (je crois depuis la version 8) de produire des messages JMS : ce système sur Oracle s'appelle Advanced Queue (AQ).

Pour réaliser ce tour de magie, on définit tout d'abord un trigger sur la table (trigger en update, create,delete etc...). Ce trigger appellera une procédure stockée qui se chargera d'écrire et d'envoyer un message JMS. Coté Java, on aura besoin de se connecter à la queue Oracle et d'être prévenu lorsqu'un message arrive pour le traiter ensuite.

Ca parait très simple sur le papier, et ça l'est en pratique à condition que ça marche du premier coup qui n'a pas été mon cas !! Les docs et tutorials Oracles sur la toile sont assez nombreux et simples mais malheureusement (je peux citer par exemple http://gbowyer.freeshell.org/oracle-aq.html), en cas d'erreur (j'avais une exception que je ne comprenais pas d'où elle venait) on est vite paumé pour trouver une solution. Heureusement, à travers cet article et mon expérience acquise, je pense que je pourrai en aider certains !

Les pré requis nécessaires :
  • Une base Oracle 8 au minimum installée sur un serveur. Cet article se base sur la 9i
  • Les outils clients d'Oracle pour votre base (ces outils intégrent les drivers JDBC et le nécessaire pour lire les messages Oracle) installés sur votre machine de développement. ATTENTION : je tiens à avertir, car j'ai eu le cas, comme j'avais la version 9i, ça me paraissais logique d'installer les outils clients pour la 9i. Ben non ! j'ai pas du tout réussi à faire marcher mon programmes avec les librairies pour la 9i !! J'ai mis un jour et demi pour m'en rendre compte que ça venait des bibliothèques d'Oracle ! :( (j'avais des exceptions du type AbstractError à la connexion à Oracle). J'ai téléchargé les outils pour la version 10g (pas essayé sur la version 11g), et ça marche nickel même sur la base 9i !! (Peut être téléchargé à l'adresse : http://www.oracle.com/technology/software/products/database/oracle10g/htdocs/10201winsoft.html)
  • Un environnement de développement J2EE (J2EE 5 conseillé), j'utilise pour ma part RAD 7 (Rational Application Developper)
  • Un projet J2EE avec Spring de configuré (pas la peine de présenter Spring ? ...)
Passons à la mise en pratique :

1. Création de la queue dans Oracle

Pour commencer, on va s'attacher à créer la queue sur la base Oracle.

Connectez vous sur la base avec SQL*Plus en tant que SysDBA.

Il faut créer un utilisateur qui aura accès aux queues (et pourra écrire dedans). Une fois l'utilisateur créé, il faut lui donner les droits suivants : DBMS_AQ et DBMS_AQADM
GRANT EXECUTE ON DBMS_AQ TO MON_USER;
GRANT EXECUTE ON DBMS_AQADM TO MON_USER;
où MON_USER est le nom de l'utilisateur créé


Pour créer la queue, il suffit de lancer la commande suivante :
EXEC dbms_aqadm.create_queue_table(queue_table=>'content_queue', queue_payload_type=>'sys.aq$_jms_text_message', multiple_consumers=>TRUE);
EXEC dbms_aqadm.create_queue(queue_name=>'cnt_queue', queue_table=>'content_queue');
EXEC dbms_aqadm.start_queue(queue_name=>'cnt_queue');
commit;


cnt_queue est le nom de la queue à créer.
content_queue le nom de la table où Oracle va stocker les données.
queue_payload_type est le type des données dans les messages. Ici j'ai mis texte.
Je vous laisse le soin de lire par exemple http://hell.org.ua/Docs/oreilly/oracle/bipack/ch05_05.htm pour la liste complète des paramètres.

2. Création de la procédure et du trigger sur une table

Je le rappelle, le but de la procédure est d'écrire un message JMS dans la queue créée plus haut. Cette procédure sera appelée par un trigger sur la table.

Voici comment créer la procédure, toujours à partir de SQL*Plus :
CREATE OR REPLACE PROCEDURE PROC_CACHE_CTRL_NOTIFICATION(TABLE_NAME IN VARCHAR) AS
msg SYS.AQ$_JMS_TEXT_MESSAGE;
queue_options DBMS_AQ.ENQUEUE_OPTIONS_T;
msg_props DBMS_AQ.MESSAGE_PROPERTIES_T;
msg_id RAW(16);
no_consumers_error EXCEPTION;
PRAGMA EXCEPTION_INIT(no_consumers_error, -24033);
BEGIN
-- Ensure what is sent will be a JMS message
msg := SYS.AQ$_JMS_TEXT_MESSAGE.CONSTRUCT();

msg.set_text('TABLE_NAME=' || TABLE_NAME);
DBMS_AQ.ENQUEUE( queue_name => 'cnt_queue'
, enqueue_options => queue_options
, message_properties => msg_props
, payload => msg
, msgid => msg_id);
-- Without the following, the procedure will die if noone
-- Is listening for cache control
EXCEPTION
WHEN no_consumers_error
THEN
-- Output it in case, but otherwise swallow
DBMS_OUTPUT.PUT_LINE('No interested parties are listening to cache-control messages');
END;


Cette petite procédure va écrire un message texte TABLE_NAME=la valeur passée en paramètre de la procèdure. Je vous laisse le loisir de personnaliser un peu cette procédure. Notez l'utilisation de DBMS_AQ.ENQUEUE pour poster un message.

Il faut créer désormais le trigger : sur la table Banque par exemple :
CREATE OR REPLACE TRIGGER TRGR_BANQUE
AFTER DELETE OR INSERT OR UPDATE
ON BANQUE
CALL PROC_CACHE_CTRL_NOTIFICATION('BANQUE');


3. Création des classes Java pour la connexion et réception des messages

Ouvrir votre projet J2EE avec Spring, on va créer trois classes pour la reception des messages.

Mais pour commencer, il faut modifier le classpath (Chemin de génération JAVA sous Eclipse ou RAD) :
  • Ajouter les jars aqapi13.jar et jmscommon.jar. Ces jars ce situent dans le répertoire rdbms/jlib du répertoire d'installation des outils clients d'Oracle (cf. plus haut). Si elles n'y sont pas, c'est que vous avez pas tous installé....
  • Ajouter le jar ojdbc14.jar. Ce jar est dans le répertoire jdbc/lib d'Oracle
Créer la classe de création de la connexion à la base Oracle :

package trigger;

import javax.jms.ConnectionFactory;
import oracle.jms.AQjmsFactory;

public class OracleAQTopicConnectionFactory
{

public ConnectionFactory createConnectionFactory() throws Exception
{
String url="jdbc:oracle:thin:MON_USER/MON_MDP@MON_SERVER:MON_PORT:MON_SID";

ConnectionFactory c= AQjmsFactory.getTopicConnectionFactory(url,null);
return c;
}
}

où MON_USER et MON_MDP sont respectivement le login et mot de passe de l'utilisateur ayant accés aux queues sur la base Oracle (voir plus haut)
MON_SERVEUR, MON_PORT sont le nom du serveur et le port pour se connecter à la base
MON_SID : le nom de l'instance Oracle

Note importante : vous remarquez que j'ai mis le login et mot de passe dans l'URL de connexion, je sais pas pourquoi, la connexion ne MARCHERA PAS si ces deux infos ne sont pas présentes ... (j'ai mis 3h pour m'en apercevoir !)

La deuxième classe à créer est une classe de connexion à la queue Oracle (Topic) :
package trigger;

import org.springframework.beans.factory.FactoryBean;
import oracle.jms.AQjmsSession;

import javax.jms.Topic;
import javax.jms.TopicConnectionFactory;

public class OracleAQTopicDestinationFactory implements FactoryBean {

private TopicConnectionFactory connectionFactory;
private String queueUser;
private String queueName;


public Object getObject() throws Exception {

AQjmsSession session = (AQjmsSession) connectionFactory
.createTopicConnection()
.createTopicSession(true, 0);


Topic t= session.getTopic(queueUser , queueName);
return t;
}

public Class getObjectType() {
return javax.jms.Topic.class;
}

public boolean isSingleton() {
return true;
}

public void setConnectionFactory(TopicConnectionFactory connectionFactory) {
this.connectionFactory = connectionFactory;
}

public void setQueueUser(String queueUser) {
this.queueUser = queueUser;
}

public void setQueueName(String queueName) {
this.queueName = queueName;
}
}


Enfin la troisième, est une classe qui écoute les messages. C'est celle çi qui va recevoir un message dès qu'Oracle en publie un.

package trigger;

import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;


public class OracleNotificationListener implements MessageListener
{

public void onMessage(Message message)
{
try
{
String text = ((TextMessage) message).getText();
System.out.println("Message reçus : " + text);

} catch (Throwable t)
{
t.printStackTrace();
}
}
}

A la réception d'un message, on l'affiche bêtement dans la console.

3. Paramétrage de Spring

Il ne reste plus qu'a paramétrer dans Spring pour que tout fonctionne. Dans votre applicationContext.xml, ajouter les lignes :

<beans xmlns="http://www.springframework.org/schema/beans" xsi="http://www.w3.org/2001/XMLSchema-instance" tx="http://www.springframework.org/schema/tx" schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd ">

<bean id="oracleAQJMSListener" class="trigger.OracleNotificationListener">

</bean>

<bean id="oracleAqConnFactory" bean="oracleAqConnectionFactoryHandler" method="createConnectionFactory">

<bean id="oracleAqConnectionFactoryHandler" class="trigger.OracleAQTopicConnectionFactory">
</bean>


<bean id="cnt_queue" class="trigger.OracleAQTopicDestinationFactory">
<property name="connectionFactory" ref="oracleAqConnFactory">
<property name="queueName" value="cnt_queue">
<property name="queueUser" value="MON_USER">
</property>

<bean id="oracleAqJMSQueue" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="oracleAqConnFactory">
<property name="destination" ref="cnt_queue">
<property name="messageListener" ref="oracleAQJMSListener">
<property name="pubSubDomain" value="true">
</property>
</property></property></property></bean></property></property></bean></bean></beans>

Il ne faut pas oublier d'adapter les valeur class en respectant vos packages et nom de classes (ici les classes sont dans le package trigger).
Ici la queue s'appelle cnt_queue.
Le bean oracleAqJMSQueue est le bean d'écoute des messages (troisième classe créé).

Voila c'est tout !

Pour tester :

Lancer votre application.
Effectuez une modification sur la table où est le trigger
Un message devrait apparaitre dans la console... ça marche !!

mardi 9 juin 2009

Erreur IWAE0006E au déploiement d'une application WebSphere

Bonjour,
depuis 3 jours, sur ma machine, impossible de déploier mon application J2EE sur WebSphere en utilisant RAD !

J'avais une erreur IWAE0006E dans la console se plaignant que mon application n'était pas valide et que le web.xml manquait à l'appel ! Que nenni ! Tout était parfait pourtant dans mon projet sous RAD, j'ai trituré dans tous les sens pendant 3 jours pensant que le problème venait de ma configuration (tout marchait bien il y a encore 1 semaine!)...

J'aurai du en fait chercher du coté de mon ami Google : voici un lien qui corrigera le problème (en anglais) : http://www-01.ibm.com/support/docview.wss?uid=swg21255956

Pour résumer (je vous laisse lire l'article d'IBM), si par hasard vous avez modifié vos répertoires sources du projet (propriétés du projet/chemin de génération JAVA/Sources) et que vous avez le malheur d'avoir mis une source vers un répertoire qui n'existe plus, ça empeche le déploiement de l'application avec l'erreur enigmatique IWAE0006E dans la console...

La combine consiste à virer de la configuration du projet les répertoires sources qui n'existent plus (en modifiant le fichier settings/org.eclipse.wst.common.component de votre projet)

Voili, bon courage avec RAD et WebSphere ! (il en faut parfois!)

vendredi 5 juin 2009

Erreur : SQLGrammarException: could not get next sequence value avec Hibernate et JPA

Bonjour,
si vous utilisez Hibernate avec JPA sur une base Oracle, sur les clés, vous pouvez avoir l'exception suivante :

org.hibernate.exception.SQLGrammarException: could not get next sequence value


La raison de l'erreur est pour les clés auto incrémentées. Il faut pour que ça marche, créer une séquence.
On va mettre en place la solution sur mon exemple : une table Banque

Voici ma classe de mapping :
@Entity //entité JPA
public class Banque
{
@Id //c'est la clé primaire
@GeneratedValue() //c'est une clé générée (auto incrémentée)
@Column(name="refbqe") //nom de la colonne dans la table
private Integer id;

//les colonnes dans la table
private String Cdepos;

...

+ getter/setter
}


Connectez vous sur votre base et crééz une séquence BANQUE_SEQUENCE :

create sequence BANQUE_sequence
start with 1
increment by 1
nomaxvalue;


Cette séquence sera utilisée pour générer les clés de la table Banque. Modifier la classe Banque comme ceci :
@Entity
public class Banque
{
@Id
@SequenceGenerator(name="sequence",sequenceName="BANQUE_sequence")
@GeneratedValue(GenerationType.SEQUENCE,generator="sequence")
@Column(name="refbqe")
private Integer id;

//les colonnes dans la table
private String Cdepos;

...

+ getter/setter
}

(notez le rajout de SequenceGenerator et la modification de GeneratedValue)

Voili, c'est tout, ça devrait marcher maintenant !!

A+