10 votes

Plus d'une table trouvée dans l'espace de noms (, ) - SchemaExtractionException

J'ai été confronté à cette exception bizarre lorsque j'ai essayé de faire persister certaines valeurs dans une table en utilisant Hibernate dans une application Java. Cependant, cette exception ne se produit que pour une table/entité particulière. Pour le reste des tables, je suis en mesure d'effectuer des opérations simples via Hibernate.

Veuillez trouver ci-dessous le Stacktrace et faites-moi savoir si cela est lié au code java ou si c'est une erreur de conception de base de données.

 2016-04-28 11:52:34 ERROR XXXXXDao:44 - Failed to create sessionFactory object.org.hibernate.tool.schema.extract.spi.SchemaExtractionException: More than one table found in namespace (, ) : YYYYYYY
Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.XX.dao.XXXXXXXDao.main(XXXXXXXXDao.java:45)
Caused by: org.hibernate.tool.schema.extract.spi.SchemaExtractionException: More than one table found in namespace (, ) : YYYYYYY
    at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.processGetTableResults(InformationExtractorJdbcDatabaseMetaDataImpl.java:381)
    at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.getTable(InformationExtractorJdbcDatabaseMetaDataImpl.java:279)
    at org.hibernate.tool.schema.internal.exec.ImprovedDatabaseInformationImpl.getTableInformation(ImprovedDatabaseInformationImpl.java:109)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.performMigration(SchemaMigratorImpl.java:252)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:137)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:110)
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:176)
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:64)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:458)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:465)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:708)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
    at com.xx.dao.zzzzzzzzzzzzDAOFactory.configureSessionFactory(zzzzzzzDAOFactory.java:43)
    at com.xx.dao.zzzzzzzzzzzzDAOFactory.buildSessionFactory(zzzzzzzzzDAOFactory.java:27)
    at com.xx.dao.XXXXXXXXDao.main(XXXXXXXXDao.java:41)

Merci d'avance pour votre aide

8voto

RichB Points 121

J'ai eu le même problème et j'ai pu creuser jusqu'au code pour trouver la cause, du moins dans mon cas. Je ne sais pas si ce sera le même problème pour vous mais cela peut être utile.

D'après votre trace de pile, je vois que le paramètre hibernate.hbm2ddl.auto est configuré pour mettre à jour le schéma. Dans le cadre de cette opération, il tente de rechercher les métadonnées de toutes les tables connues d'Hibernate et, pour l'une d'entre elles, il obtient une réponse ambiguë car la requête de métadonnées renvoie plus d'une ligne de métadonnées de table ou de vue.

Dans mon cas, cela était dû à notre convention de dénomination des tables. Nous avions une table appelée (disons) "AAA_BBB" pour laquelle cela ne fonctionnait pas. Pour autant que je sache, l'utilisation d'un trait de soulignement dans le nom d'une table est parfaitement acceptable et constitue une pratique assez courante. Cependant, le trait de soulignement est également le caractère générique SQL pour un seul caractère ; en regardant dans le code des métadonnées de la base de données, je peux voir qu'il est fait un "WHERE nom_table LIKE ..." dans la méthode DatabaseMetaData.getTables(...), qui est ce qu'hibernate utilise ici.

Or, dans mon schéma, j'avais également une deuxième table appelée "AAA1BBB" et, par conséquent, ces deux tables correspondaient à la recherche de métadonnées et renvoyaient donc une ligne de métadonnées pour chacune de ces tables. La méthode Hibernate est écrite de manière à tomber si le jeu de résultats de la recherche de métadonnées de table renvoie plus d'une ligne. Je suppose qu'elle doit examiner la ou les lignes disponibles et trouver si l'une d'entre elles correspond exactement au nom de la table spécifiée.

J'ai testé ceci pour Oracle et MySQL avec le même résultat.

6voto

ashwin Points 59

Il semble que la propriété hibernate.hbm2ddl.auto définie sur update soit à l'origine du problème. Essayez de la supprimer de votre fichier de configuration hibernate.

3voto

Naor Bar Points 471

Ça va marcher :

Vérifiez le ou les schémas de votre base de données et les privilèges de l'utilisateur de la base de données ;

Le mécanisme de mise à jour d'Hibernate peut échouer avec cette exception s'il existe un autre schéma de base de données/utilisateur avec le même nom de table, et que l'utilisateur de la base de données dispose des privilèges suffisants pour visualiser cette table.

Ainsi, dans votre cas, la table 'YYYYYYY' peut se trouver dans plus d'un utilisateur de base de données/ schéma, et votre utilisateur db a des privilèges 'DBA'.

Pour résoudre ce problème, vous pouvez soit trouver et supprimer la table ambiguë, soit supprimer les privilèges superflus de l'utilisateur.

2voto

Utiliser la valeur du catalogue avec @Table c'est-à-dire :

@Entity
@Table(**catalog = "MY_DB_USER"**, name = "LOOKUP")
public class Lookup implements Serializable {

}

Je n'ai plus cette erreur maintenant. J'espère que cela fonctionnera.

2voto

Abbas Tofighi Points 41

Une autre situation peut se produire en dehors de ce que RichB a dit. dans ORACLE chaque utilisateur a un schéma séparé, Par conséquent, il y a probablement deux tables avec le même nom dans deux schémas différents. alors vous devez spécifier votre schéma par défaut dans persistence.xml avec la propriété suivante

<property name="hibernate.default_schema" value="username"/>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X