2009-01-26 21 views
3

Je suis en train d'exécuter cette requête JPQL:JPA: 'SELECT DISTINCT avec des colonnes de type BLOB

SELECT DISTINCT i FROM Table i JOIN i.other o 

qui échoue rapidement avec:

« Exception interne: java.sql.SQLException: Les colonnes de type 'BLOB' ne peuvent pas être utilisées dans les instructions CREATE INDEX, ORDER BY, GROUP BY, UNION, INTERSECT, EXCEPT ou DISTINCT car les comparaisons ne sont pas prises en charge pour ce type. "

Cette erreur est logique pour moi, mais comment la contourner?

+0

Quelle base de données utilisez-vous? Il serait utile de savoir ... –

+0

J'utilise Java DB (derby) et EclipseLink – Cogsy

Répondre

3

Vous pouvez stocker un hachage ou une somme de contrôle de l'objet blob dans une autre colonne, et utiliser votre opérateur distinct pour cela.

Exemple:

SELECT i from Table WHERE id IN (
    SELECT id FROM (
    SELECT MIN(id) AS id, hash_of_i FROM Table GROUP BY hash_of_i 
       ) t 
           ) 

Je suis sûr que vous pouvez écrire SQL avec plus d'élégance, mais il vous donnera une idée. Éditer - vous venez de vous rendre compte qu'en utilisant cela, vous pouvez vous passer entièrement de l'opérateur Distinct (il sera équivalent fonctionnellement en le supprimant).

Edit 2 - Je ne suis pas sûr que ma première version a fonctionné, ont donc réécrit

+0

Je crois distinct compare réellement chaque colonne sélectionnée. Le 'i' se réfère à l'ensemble de l'objet lié à cette table, à savoir. toutes les colonnes. Moins que cela et JPA ne reconstruira pas mes objets ... – Cogsy

+0

Il le fait, vous devez juste être un peu plus mignon avec votre SQL ... Je vais ajouter un exemple à ma réponse – DanSingerman

0

valeurs dans les colonnes de type BLOB ne sont que des pointeurs vers le stockage de données réelles. Pour appliquer l'un de ces opérateurs, vous devez charger les données du BLOB et implémenter votre propre logique puisque les données peuvent représenter n'importe quoi (image, texte ...)

2

Une inspiration de HermanD m'a conduit à cette solution de travail :

SELECT i FROM Table i WHERE EXISTS (
    SELECT e FROM Table e JOIN e.other o WHERE e.id=i.id 
) 
0

Utilisez setResultTransformer (Criteria.DISTINCT_ROOT_ENTITY) au lieu de distinct sur votre requête.