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 :

JPA - JOIN FETCH sur relation OneToOne en EAGER = ArgumentException error


Sujet :

JPA Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    kij
    kij est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 362
    Par défaut JPA - JOIN FETCH sur relation OneToOne en EAGER = ArgumentException error
    Bonjour,

    J'ai une erreur lorsque j'effectue une NamedQuery avec un JOIN FETCH sur une relation partagée OneToOne en EAGER. Par partager je veux dire que cette relation se trouve dans une entité abstraite.

    En gros voici la composition de mes entités:
    1. Entity A, étend l'entité abstraite E.

    1. Entity A possède une relation oneToMany sur l'entité B.

    1. Entity B, étend l'entité abstraite E.

    1. Entité abstraite E possède la définition de l'ID, ainsi qu'une relation OneToOne sur Entité C avec fetch type EAGER.

    1. Entité C, possède la relation inverse sur l'entité abstraite E (commune à A et B donc)



    Voici le code simplifié qui pose problème.

    Entité A
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    @Entity
    @Table(name = "TABLE_A")
    @Access(AccessType.FIELD)
    @NamedQueries({
       @NamedQuery(name = "findADetails", query = "SELECT a FROM A a WHERE a.customKey.key = :customKey")})
    public class A extends abstractEntity {
     
       @Embedded
       private CustomEmbeddedKey customKey;
     
       @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "entityA")
       private List<B> bEntities;
     
       ...
    }
    Entité B
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    @Entity
    @Table(name = "TABLE_B")
    @Access(AccessType.FIELD)
    public class B extends abstractEntity {
     
       @ManyToOne(fetch = FetchType.LAZY, targetEntity = A.class)
       @JoinColumn(name = "FK_A_ID")
       private A entityA;
     
       ...
    }
    Entité abstraite
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    @Entity
    @Access(AccessType.FIELD)
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    @SequenceGenerator(name = "TOTO_ID_SEQ", sequenceName = "TOTO_ID_SEQ", initialValue = 1, allocationSize = 1)
    public abstract class abstractEntity {
     
       @Id
       @Column(name = "ID")
       @GeneratedValue(generator = "...", strategy = GenerationType.SEQUENCE)
       private Long id;
     
       @OneToOne(mappedBy = "...", fetch = FetchType.EAGER)
       private C anotherEntity;
     
       @OneToMany(mappedBy = "...", fetch = FetchType.LAZY)
       private List<D> anotherEntities;
     
       ...
     
    }
    Clé custom
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    @Embeddable
    @Access(AccessType.FIELD)
    public class CustomEmbeddedKey {
     
       @Column(name = "...", length = ...)
       private String key;
     
       ...
    }
    Exemple Dao
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    // Dao utilisant la NamedQuery
    public class Dao {
     
       ...
     
       // Code d'exemple
       public A bidule (String queryParam) {
          TypedQuery<A> query = createNamedQuery("findADetails", A.class);
          query.setParameter("customKey", queryParam);
          List<A> aEntitiesFound = query.getResultList();
          return aEntitiesFound.get(0);
       }
     
       ...
    }
    Problème: Via un test junit, lorsque j'exécute ma namedQuery via le Dao, tout se passe bien.
    Par contre, souhaitant récupérer la liste de mes entités B configurée en LAZY en une seule requête, si j'ajoute un JOIN FETCH dans la NamedQuery comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT a FROM A a JOIN FETCH a.bEntities WHERE a.customKey.key = :customKey
    J'obtiens la stack d'erreurs suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    javax.ejb.EJBTransactionRolledbackException: The transaction has been marked rollback only because the bean encountered a non-application exception :javax.ejb.EJBTransactionRolledbackException : The transaction has been marked rollback only because the bean encountered a non-application exception :org.apache.openjpa.persistence.ArgumentException : The specified parameter of type "class org.apache.openjpa.util.LongId" is not a valid query parameter.
    	at org.apache.openejb.core.ivm.BaseEjbProxyHandler.convertException(BaseEjbProxyHandler.java:345)
    	... 
    Caused by: <openjpa-2.2.0-r422266:1244990 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: The specified parameter of type "class org.apache.openjpa.util.LongId" is not a valid query parameter.
    FailedObject: SELECT a FROM A a JOIN FETCH a.bEntities WHERE a.customKey.key = :customKey [java.lang.String]
    	at org.apache.openjpa.jdbc.sql.DBDictionary.setUnknown(DBDictionary.java:1458)
    	...

    Après les tests et résultats suivants:
    1. T1 = Passer la relation partagée oneToOne en LAZY au lieu de EAGER -> OK

    1. T1 + ajouter un JOIN FETCH sur la relation oneToOne dans la namedQuery -> KO

    1. Virer la relation oneToOne de la classe abstraite pour l'ajouter dans l'entity A et B, et modifier l'entité C pour y acceuillir les relations inverses vers A et B -> OK


    Il apparait donc que le problème viendrait du fait que la relation oneToOne sur l'entité C soit partagée, i.e présente dans la classe abstratire.

    Est-ce que quelqun sait pourquoi ? Y -a-t-il un problème du fait que lorsque openJpa tente d'améliorer la requête, il n'arrive pas à matcher les ID issue de cette relation entre celui de A et celui de B (qui pourtant ne sont pas les mêmes puisque la régle de génération est commune sur l'entité abstraite)

    Bref, si une âme charitable pourrait m'aider à y voir plus clair, ce serait très sympa

    Merci d'avance pour toute aide.

  2. #2
    kij
    kij est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 362
    Par défaut
    J'ai trouvé mon problème.

    Cela vient en fait d'une limitation d'openJPA sur le eager fetching avec un inheritance type à TABLE_PER_CLASS.

    Les alternatives sont expliquées sur
    cet autre thread que j'ai posté.

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

Discussions similaires

  1. inner join fetch sur une query refusé
    Par nestr dans le forum NHibernate
    Réponses: 0
    Dernier message: 26/06/2015, 12h08
  2. Relation oneToOne sur clef primaire
    Par hebus44 dans le forum Doctrine2
    Réponses: 2
    Dernier message: 26/02/2012, 15h49
  3. Api Criteria left join fetch sur plusieur table
    Par makroute dans le forum Hibernate
    Réponses: 1
    Dernier message: 16/05/2011, 11h36
  4. Relation gauche (left join) prob sur serveur
    Par Rocknacro dans le forum Requêtes
    Réponses: 1
    Dernier message: 13/02/2007, 11h57
  5. Requetes sur relation n:1
    Par skyo dans le forum Langage SQL
    Réponses: 10
    Dernier message: 18/07/2005, 14h35

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