2010-09-23 4 views
3

J'ai commencé à créer des mappages JPA/Hibernate pour une base de données existante basée sur Oracle. A un (début ...) point j'ai une relation plusieurs-à-plusieurs entre les tables (FOO, BAR, table de jointure avec des champs supplémentaires: FOO_BAR). J'ai donc défini trois entités, créé une classe Id embeddable pour la table de jointure, en suivant strictement quelques exemples d'un bon livre (?!).Aide nécessaire pour JPA/Hibernate - problèmes de création de classes d'entités

Je peux sélectionner un Foo mais chaque fois que j'essaie de lire les barres liées du jeu de résultats, je reçois une "SQLException: Aucune donnée trouvée" ou une "SQLException: Erreur générale (S1000)". Je peux basculer entre les deux en changeant simplement certains types java de beans entité ...

Le journal contient le cas la ligne n suivante de la « Aucune donnée trouvée » Erreur:

INFO org.hibernate.type.LongType - could not read column value from result set: Foo1_2_; No data found 

Les colonnes FOO_ID et BAR_ID sont définis comme NUMBER(22). J'ai d'abord essayé les types Long, cela a abouti à "Aucune donnée trouvée", Double conduit à "Erreur générale". Ensuite, j'ai lu quelque part que le mappage standard pour NUMBER est BigDecimal (-> "Erreur générale"), j'ai essayé BigInteger à la place (-> "Aucune donnée trouvée").

Je suis perdu.

Lorsque je récupère l'instruction sql des journaux et l'utilise avec "natif" jdbc, ... cela fonctionne correctement.

PreparedStatement prep = con.prepareStatement(sqlQueryFromHibernateLogs); 
prep.setBigDecimal(1, new BigDecimal(1)); 
ResultSet rs = prep.executeeQuery(); // result set has the correct values... 

Toute aide, suggestion, pointeur vers des ressources utiles est fortement appréciée. Oh, une dernière chose à mentionner: je suis 'forcé' d'utiliser le pont JdbcOdbc. Il est vraiment un ancien système ...


Mon instruction select va comme ceci:

List<Foo> foos = em.createQuery("select f from Foo f order by f.name").getResultList(); 

Modifier

Versions - Je suis lié aux bibliothèques de mise en veille prolongée que sont livrés avec le framework de jeu (1.0.3.2). Le fichier hibernate3.jar n'a pas d'informations de version utiles (rien dans le manifeste, Version#getVersionString() indique [WORKING]), les autres fichiers hibernatexxx rapportent comme 3.1.0.GA (validateur) ou 3.4.0.GA (entitymanager).


Edit 2

J'ai réduit les classes au strict minimum les erreurs encore présentes. Voilà ce que je l'ai fait:

Foo.java

@Entitiy @Table(name="FOO") 
public class Foo { 
    @Id @Column(name="FOO_ID") 
    private BigInteger fooId; 

    Foo(){} 

    @OneToMany(mappedBy="foo") 
    private Set<FooBar> fooBars = new HashSet<FooBar>(); 
} 

Bar.java

@Entitiy @Table(name="BAR") 
public class Bar { 
    @Id @Column(name="BAR_ID") 
    private BigInteger fooId; 

    Bar(){} 

    @OneToMany(mappedBy="bar") 
    private Set<FooBar> fooBars = new HashSet<FooBar>(); 
} 

FooBar.java

@Entitiy @Table(name="FOOBAR") 
public class FooBar { 

    @Embeddable 
    public static class Id implements Serializable { 
    @Column(name="FOO_ID") 
    private BigInteger fooId; 
    @Column(name="BAR_ID") 
    private BigInteger barId; 

    Id() {} 

    // implementations of hashcode and equals 

    } 

    @Embedded 
    private Id id = new Id(); 

    @ManytoOne @JoinColumn(name = "FOO_ID", insertable=false, updatable=false) 
    private Foo foo; 

    @ManytoOne @JoinColumn(name = "BAR_ID", insertable=false, updatable=false) 
    private Bar bar; 

    FooBar(){} 
} 

FOO_ID et BAR_ID sont définis comme NUMBER(22) sur la base de données Oracle. L'exemple ci-dessus conduit à l'erreur "Aucune donnée trouvée", en remplaçant BigInteger par Long dans "Erreur générale". Et l'envoi de la même expression SQL sur le pont donne un jeu de résultats correct ...

+1

* Je suis 'forcé' d'utiliser le pont JdbcOdbc * Oh mon ... Au cas où cela pourrait être pertinent, quel dialecte utilisez-vous? Quelle version d'Hibernate? –

+0

@Pascal - le dialecte est 'Oracle10gDialect', hibernate est 3-dot-quelque chose (il faut le chercher). Mais, comme je l'ai dit, JDBC natif (même déclaration) fonctionne avec le pont ... –

+0

Oui, j'ai compris. Mais Hibernate est impliqué dans le problème, IMO :) –

Répondre

0

Trouvé la solution ou - au moins - découvert, que l'approche ne peut pas fonctionner avec les outils donnés (hibernate, pont JdbcOdbc) :

Un peu plus de googeling m'a finalement envoyé à this (german) page, où quelqu'un avait un problème similaire: une SQLException No data found en travaillant avec le pont. Quelqu'un d'autre a répondu que le code est correct mais que c'est un problème avec le pont JdbcOdbc qui ne supporte pas la lecture d'un ensemble de résultats plus d'une fois. Je ne peux pas clarifier, si j'ai le même problème ici, mais je suis assez sûr que c'est ce cas ou un cas similaire et le problème est lié à l'utilisation du pont avec Hibernate/JPA.

Pour mon cas très spécial: J'ai résolu le problème en l'ignorant après ... finalement découvrir que je peut utiliser le pilote oracle oci. (sigh)

Merci à tous ceux qui ont essayé de suivre mon message et de réfléchir à une solution!

+0

Avant de mettre à votation, serait possible de marquer n'importe quel BigInteger @Column comme @Column (presicion = 22) et voir ce qui se passe. Bien que la précision soit utilisée pour les valeurs BigDecimal (http://download.oracle.com/javaee/5/api/javax/persistence/Column.html#precision%28%29) Cela fonctionne avec un BigInteger (http: // stackoverflow .com/questions/2916838) –