Hibernate + implémentation like pour champ de type Number
2 réponses
fabien.perie
Bonjour,
dans une base oracle, j'ai un champ exercice o=F9 on stocke des ann=E9es
sous la forme de "Number(4)".
J'utilise Hibernate et je souhaite pouvoir effectuer une recherche en
disant "renvoie moi toutes les dates qui commencent par : 20 par
exemple", en gros un sorte de 'like' mais pour du num=E9rique.
Pour cela j'ai cr=E9e la classe suivante :
/**
* Classe permettant d'effectuer l'=E9quivalent d'un 'like' sur
* une propri=E9t=E9 num=E9rique (Number ou Integer)
*/
public class LikeIntegerExpression implements Criterion
{
private String propertyName;
private Integer value;
public String toSqlString(Criteria criteria, CriteriaQuery
criteriaQuery) throws HibernateException {
String[] columns =3D criteriaQuery.getColumnsUsingProjection(criteria,
propertyName);
Type type =3D criteriaQuery.getTypeUsingProjection(criteria,
propertyName);
StringBuffer fragment =3D new StringBuffer();
Hibernate effectue bien la requete, mais il plante juste apr=E8s en
disant : =AB
[ERROR JDBCExceptionReporter] Index de colonne non valide
[11:33:45.588]
org.hibernate.util.JDBCExceptionReporter.logExceptions(JDBCExceptionReporte=
r=2Ejava:72)
Exception : Une erreur non typ=E9e a =E9t=E9 lev=E9 : could not execute
query =BB
Si j'effectue la requ=EAte g=E9n=E9r=E9e par Toad sous Toad, la requ=EAte
s'ex=E9cute bien...
Je pense que mon erreur vient de l'impl=E9mentation de la m=E9thode : =AB
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery
criteriaQuery) =BB car je n'ai pas tr=E8s bien compris ce que doit faire
cette m=E9thode ? Qu'en pensez-vous ?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
simon.oualid
Perso je gérerais ça directement au niveau d'oracle. Soit en utilisant directement un datatype VARCHAR2 (avec un TO_NUMBER dans les WHERE si tu souhaites faire des comparaisons), soit en utilisant TO_CHAR.
Pour l'intégration hibernate, tu peux utiliser une vue (en lecture seule). Si tu as besoin de lecture / ecriture et que la volumétrie reste raisonnable, crée 2 colonnes, alimente le champs en INTEGER, et crée un trigger qui va stocker la même donnée en VARCHAR2 à chaque insert/update (pour pouvoir faire ton LIKE simplement ensuite).
Je crois d'ailleurs, mais c'est à vérifier, que les dernière versions d'oracle (>8i) supportent directement les LIKE sur les champs NUMBER - et dérivés - par l'utilisation d'un TO_CHAR implicite.
J'espère que tout ça pourra t'aider.
Symon
wrote:
Bonjour,
dans une base oracle, j'ai un champ exercice où on stocke des années sous la forme de "Number(4)". J'utilise Hibernate et je souhaite pouvoir effectuer une recherche en disant "renvoie moi toutes les dates qui commencent par : 20 par exemple", en gros un sorte de 'like' mais pour du numérique.
Pour cela j'ai crée la classe suivante :
/** * Classe permettant d'effectuer l'équivalent d'un 'like' sur * une propriété numérique (Number ou Integer) */ public class LikeIntegerExpression implements Criterion { private String propertyName; private Integer value;
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName); Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName); StringBuffer fragment = new StringBuffer();
Hibernate effectue bien la requete, mais il plante juste après en disant : « [ERROR JDBCExceptionReporter] Index de colonne non valide
[11:33:45.588] org.hibernate.util.JDBCExceptionReporter.logExceptions(JDBCExceptionRepor ter.java:72) Exception : Une erreur non typée a été levé : could not execute query »
Si j'effectue la requête générée par Toad sous Toad, la requête s'exécute bien...
Je pense que mon erreur vient de l'implémentation de la méthode : « public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) » car je n'ai pas très bien compris ce que doit faire cette méthode ? Qu'en pensez-vous ?
HELP ME !!! Merci d'avance.
Fabien
Perso je gérerais ça directement au niveau d'oracle. Soit en
utilisant directement un datatype VARCHAR2 (avec un TO_NUMBER dans les
WHERE si tu souhaites faire des comparaisons), soit en utilisant
TO_CHAR.
Pour l'intégration hibernate, tu peux utiliser une vue (en lecture
seule). Si tu as besoin de lecture / ecriture et que la volumétrie
reste raisonnable, crée 2 colonnes, alimente le champs en INTEGER, et
crée un trigger qui va stocker la même donnée en VARCHAR2 à chaque
insert/update (pour pouvoir faire ton LIKE simplement ensuite).
Je crois d'ailleurs, mais c'est à vérifier, que les dernière
versions d'oracle (>8i) supportent directement les LIKE sur les champs
NUMBER - et dérivés - par l'utilisation d'un TO_CHAR implicite.
J'espère que tout ça pourra t'aider.
Symon
fabien.perie@gmail.com wrote:
Bonjour,
dans une base oracle, j'ai un champ exercice où on stocke des années
sous la forme de "Number(4)".
J'utilise Hibernate et je souhaite pouvoir effectuer une recherche en
disant "renvoie moi toutes les dates qui commencent par : 20 par
exemple", en gros un sorte de 'like' mais pour du numérique.
Pour cela j'ai crée la classe suivante :
/**
* Classe permettant d'effectuer l'équivalent d'un 'like' sur
* une propriété numérique (Number ou Integer)
*/
public class LikeIntegerExpression implements Criterion
{
private String propertyName;
private Integer value;
public String toSqlString(Criteria criteria, CriteriaQuery
criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(criteria,
propertyName);
Type type = criteriaQuery.getTypeUsingProjection(criteria,
propertyName);
StringBuffer fragment = new StringBuffer();
Hibernate effectue bien la requete, mais il plante juste après en
disant : «
[ERROR JDBCExceptionReporter] Index de colonne non valide
[11:33:45.588]
org.hibernate.util.JDBCExceptionReporter.logExceptions(JDBCExceptionRepor ter.java:72)
Exception : Une erreur non typée a été levé : could not execute
query »
Si j'effectue la requête générée par Toad sous Toad, la requête
s'exécute bien...
Je pense que mon erreur vient de l'implémentation de la méthode : «
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery
criteriaQuery) » car je n'ai pas très bien compris ce que doit faire
cette méthode ? Qu'en pensez-vous ?
Perso je gérerais ça directement au niveau d'oracle. Soit en utilisant directement un datatype VARCHAR2 (avec un TO_NUMBER dans les WHERE si tu souhaites faire des comparaisons), soit en utilisant TO_CHAR.
Pour l'intégration hibernate, tu peux utiliser une vue (en lecture seule). Si tu as besoin de lecture / ecriture et que la volumétrie reste raisonnable, crée 2 colonnes, alimente le champs en INTEGER, et crée un trigger qui va stocker la même donnée en VARCHAR2 à chaque insert/update (pour pouvoir faire ton LIKE simplement ensuite).
Je crois d'ailleurs, mais c'est à vérifier, que les dernière versions d'oracle (>8i) supportent directement les LIKE sur les champs NUMBER - et dérivés - par l'utilisation d'un TO_CHAR implicite.
J'espère que tout ça pourra t'aider.
Symon
wrote:
Bonjour,
dans une base oracle, j'ai un champ exercice où on stocke des années sous la forme de "Number(4)". J'utilise Hibernate et je souhaite pouvoir effectuer une recherche en disant "renvoie moi toutes les dates qui commencent par : 20 par exemple", en gros un sorte de 'like' mais pour du numérique.
Pour cela j'ai crée la classe suivante :
/** * Classe permettant d'effectuer l'équivalent d'un 'like' sur * une propriété numérique (Number ou Integer) */ public class LikeIntegerExpression implements Criterion { private String propertyName; private Integer value;
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName); Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName); StringBuffer fragment = new StringBuffer();
Hibernate effectue bien la requete, mais il plante juste après en disant : « [ERROR JDBCExceptionReporter] Index de colonne non valide
[11:33:45.588] org.hibernate.util.JDBCExceptionReporter.logExceptions(JDBCExceptionRepor ter.java:72) Exception : Une erreur non typée a été levé : could not execute query »
Si j'effectue la requête générée par Toad sous Toad, la requête s'exécute bien...
Je pense que mon erreur vient de l'implémentation de la méthode : « public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) » car je n'ai pas très bien compris ce que doit faire cette méthode ? Qu'en pensez-vous ?
HELP ME !!! Merci d'avance.
Fabien
chrtela
wrote:
dans une base oracle, j'ai un champ exercice où on stocke des années sous la forme de "Number(4)". J'utilise Hibernate et je souhaite pouvoir effectuer une recherche en disant "renvoie moi toutes les dates qui commencent par : 20 par exemple", en gros un sorte de 'like' mais pour du numérique.
En gros, tu veux faire un filtre sur les années 2000 à 2099 ? Pourquoi ne pas générer un "WHERE year BETWEEN 2000 AND 2099", plutôt que de faire une conversion vers du char/varchar/varchar2 ?
Car une conversion rend typiquement difficile voire impossible l'utilisation d'un index.
Donc, crée plutôt un "BetweenIntegerExpression" (si ça n'existe pas, je ne connais pas assez Hibernate pour l'affirmer/l'infirmer).
fabien.perie@gmail.com wrote:
dans une base oracle, j'ai un champ exercice où on stocke des années
sous la forme de "Number(4)".
J'utilise Hibernate et je souhaite pouvoir effectuer une recherche en
disant "renvoie moi toutes les dates qui commencent par : 20 par
exemple", en gros un sorte de 'like' mais pour du numérique.
En gros, tu veux faire un filtre sur les années 2000 à 2099 ? Pourquoi ne
pas générer un "WHERE year BETWEEN 2000 AND 2099", plutôt que de faire une
conversion vers du char/varchar/varchar2 ?
Car une conversion rend typiquement difficile voire impossible l'utilisation
d'un index.
Donc, crée plutôt un "BetweenIntegerExpression" (si ça n'existe pas, je ne
connais pas assez Hibernate pour l'affirmer/l'infirmer).
dans une base oracle, j'ai un champ exercice où on stocke des années sous la forme de "Number(4)". J'utilise Hibernate et je souhaite pouvoir effectuer une recherche en disant "renvoie moi toutes les dates qui commencent par : 20 par exemple", en gros un sorte de 'like' mais pour du numérique.
En gros, tu veux faire un filtre sur les années 2000 à 2099 ? Pourquoi ne pas générer un "WHERE year BETWEEN 2000 AND 2099", plutôt que de faire une conversion vers du char/varchar/varchar2 ?
Car une conversion rend typiquement difficile voire impossible l'utilisation d'un index.
Donc, crée plutôt un "BetweenIntegerExpression" (si ça n'existe pas, je ne connais pas assez Hibernate pour l'affirmer/l'infirmer).