IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JPA Java Discussion :

Requête avec clause WHERE sur un ArrayList d'entiers stocké sous forme de BLOB


Sujet :

JPA Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 61
    Points : 109
    Points
    109
    Par défaut Requête avec clause WHERE sur un ArrayList d'entiers stocké sous forme de BLOB
    Bonjour à tous,

    J'utilise JPA 2.0 avec Glassfish. Derrière il y a une BD PostGreSql.
    J'ai une entité qui contient une ArrayList d'entiers int. Notez que la classe ArrayList reste générique puisque je ne peux pas la paramétrer avec un type primitif tel que int. Cet attribut est stocké sous forme de BLOB en base de donnée, ce qui ne constitue pas un problème pour moi à priori.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Entity
    public class SnmpOid implements Serializable {
    	@Id
    	@SequenceGenerator(name = "SNMP_OID_SEQ", sequenceName= "SNMP_OID_SEQ")
    	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="SNMP_OID_SEQ")
    	private Long id;
    	private String label;
    	private ArrayList oid; // Attribut en question!
    	private boolean pollable;
    	@Transient
    	private String oidString = null;
    ...
    Maintenant, je souhaite faire une requête qui me renvoit uniquement l'entité dont l'attribut ArrayList d'entier correspond à celui que je passe en paramètre. Une comparaison des représentations binaires devrait me suffire par exemple.

    J'ai essayé directement en JPQL:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    		String jpqlQuery = "SELECT c FROM SnmpOid c WHERE c.oid = :poid";
    		Query query = em.createQuery(jpqlQuery);
    		query.setParameter("poid", (Object)oid);
    		return query.getResultList();
    ou via un CriteriaBuilder:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    		CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
    		CriteriaQuery cq = cb.createQuery();
    		Root<SnmpOid> snmpOid = cq.from(SnmpOid.class);
    		cq.where(cb.equal(snmpOid.get(SnmpOid_.oid), (Object)oid));
    		cq.select(snmpOid);
    		Query q = getEntityManager().createQuery(cq);
    		return q.getResultList();
    Mais je récolte l'erreur suivante:

    ATTENTION: Local Exception Stack:
    Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException
    Internal Exception: org.postgresql.util.PSQLException: ERREUR: l'opérateur n'existe pas : bytea = record
    Indice*: Aucun opérateur ne correspond au nom donné et aux types d'arguments.
    Vous devez ajouter des conversions explicites de type.
    Position*: 57
    Error Code: 0
    Call: SELECT ID, LABEL, OID, POLLABLE FROM SNMPOID WHERE (OID = (?,?,?,?,?,?,?,?,?,?,?,?,?,?))
    bind => [14 parameters bound]
    Query: ReadAllQuery(referenceClass=SnmpOid sql="SELECT ID, LABEL, OID, POLLABLE FROM SNMPOID WHERE (OID = ?)")
    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
    ...
    J'ai l'impression qu'il considère mon ArrayList comme une liste de paramètres pour la requête et non comme un objet binaire à comparer.

    Quelqu'un aurait-il une idée pour que ma recherche basée sur une liste d'entier se passe correctement?
    Merci!

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par Jean Meurtrier Voir le message
    Notez que la classe ArrayList reste générique puisque je ne peux pas la paramétrer avec un type primitif tel que int.
    Tu ne peux pas y stocker des type primitif non plus! Ce sont des Integer que tu stocke dedans, et donc ArrayList<Integer>
    Cet attribut est stocké sous forme de BLOB en base de donnée, ce qui ne constitue pas un problème pour moi à priori.
    Sauf qu'en SQL les blob,clob, etc ne sont pas utilisables dans des clauses where.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 61
    Points : 109
    Points
    109
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Tu ne peux pas y stocker des type primitif non plus! Ce sont des Integer que tu stocke dedans, et donc ArrayList<Integer>

    Sauf qu'en SQL les blob,clob, etc ne sont pas utilisables dans des clauses where.
    Je n'ai pas de problème à ajouter des types primitifs avec la fonction "add" et à stocker la liste dans la BD. Par contre il est possible que ce int soit implicitement wrappé dans un Integer.

    Sinon je redoutais en effet qu'un BLOB ne puisse pas être utilisé dans une clause WHERE. C'est dommage car la liste est très courte, juste quelques éléments. Je vais certainement utiliser la représentation String pour ma comparaison plutôt que la liste d'entiers.

    Merci pour ta réponse en tout cas!

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par Jean Meurtrier Voir le message
    Je n'ai pas de problème à ajouter des types primitifs avec la fonction "add" et à stocker la liste dans la BD. Par contre il est possible que ce int soit implicitement wrappé dans un Integer.
    la signature de add, c'est add(T) avec T le typage de ta liste (dans ton code "Object"), donc oui il y a autoboxing vers Integer.

    C'est en général un très mauvaise idée de ne pas typer les generics. Si vous ne savez pas leur type, utilisez <?>. Si vous voulez autorisez n'importe quoi, utilisez <Object>

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 61
    Points : 109
    Points
    109
    Par défaut
    OK. Je vais explicitement typer ma liste en Integer. Mais elle sera @Transcient et la représentation String sera persistée à la place pour permettre des comparaisons.
    Merci!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 11
    Dernier message: 21/12/2014, 22h36
  2. Réponses: 2
    Dernier message: 08/09/2011, 18h20
  3. requête avec un where sur une date
    Par tibofo dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 06/02/2011, 20h58
  4. [AC-2007] Requête DELETE * avec clause WHERE
    Par al_bert dans le forum Requêtes et SQL.
    Réponses: 8
    Dernier message: 13/05/2009, 17h03
  5. [DTS] Problème avec clause WHERE sur Date
    Par bibou dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 28/06/2006, 12h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo