web-dev-qa-db-fra.com

Plusieurs tables trouvées dans un espace de noms (,) - SchemaExtractionException

J'ai fait face à cette exception bizarre en essayant de conserver 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 et pour le reste des tables, je peux effectuer des opérations crud via Hibernate.

Veuillez trouver ci-dessous le Stacktrace et laissez-moi savoir s'il s'agit du code Java ou s'il s'agit d'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

10
Anuj

J'ai eu le même problème et j'ai pu creuser dans le 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.

À partir de votre trace de pile, je peux voir que vous avez configuré hibernate.hbm2ddl.auto pour mettre à niveau le schéma. Dans ce cadre, il essaie de rechercher les métadonnées de toutes les tables dont Hibernate a connaissance et l'une d'entre elles 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 nommage des tables. Nous avions une table appelée (par exemple) "AAA_BBB" pour laquelle cela tournait mal. Maintenant, l'utilisation d'un trait de soulignement dans le nom de la table est tout à fait acceptable, à ma connaissance, et est une pratique assez courante. Cependant, le trait de soulignement est également le caractère générique SQL pour un caractère unique; En regardant dans le code pour les métadonnées de la base de données, je peux voir qu'il fait une méthode "WHERE nom_table LIKE ..." dans la méthode DatabaseMetaData.getTables (...), qui est utilisée ici par hibernate. 

Maintenant, dans mon schéma, j'avais également une deuxième table appelée "AAA1BBB" et par conséquent, les deux 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 pour tomber si le jeu de résultats de la recherche de métadonnées de table renvoie plus d'une ligne. J'imagine qu'il devrait examiner les lignes disponibles et rechercher s'il en existe une qui correspond exactement au nom de la table spécifiée.

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

10
RichB

Semble que la propriété mise à jour par hibernate.hbm2ddl.auto est la cause du problème ici. Essayez de le supprimer de votre xml hibernate config.

6
ashwin

Cela fonctionnera:  

Vérifiez votre schéma de base de données et vos privilèges d’utilisateur de base de données; 

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

Ainsi, dans votre cas, la table 'AAAAAAAA' peut être trouvée dans plusieurs utilisateurs/schémas de base de données et votre utilisateur de base de données dispose des privilèges 'DBA'.

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

3
Naor Bar

Une autre situation peut se produire sauf ce qui a été dit, cher RichB. dans Oracle, chaque utilisateur a un schéma distinct, Par conséquent, il existe probablement des tables de remorquage portant le même nom dans deux schémas différents . Vous devez donc spécifier votre schéma par défaut dans persistence.xml propriété

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

Utilisez la valeur de catalogue avec @Table, c'est-à-dire:

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

}

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

2

Nous avions une application Spring Data/JPA et cette erreur a commencé à se produire après la mise à niveau vers Postgres 10.6 (à partir de 10).

Notre solution était la suivante dans notre classe de configuration JPA: notez la nouvelle ligne commentée, 

props.put("hibernate.hbm2ddl.auto", "none"); //POSTGRES 10 --> 10.6 migration

Classe:

@Configuration
@EnableJpaRepositories(basePackages = "app.dao")
@ComponentScan(basePackages = { "app.service" })
@EnableTransactionManagement
public class JpaConfig {

    @Autowired
    DataSource dataSource;

    @Bean
    public Map<String, Object> jpaProperties() {
        Map<String, Object> props = new HashMap<String, Object>();
        props.put("hibernate.dialect", PostgreSQL95Dialect.class.getName());
        props.put("hibernate.hbm2ddl.auto", "none"); //POSTGRES 10 --> 10.6 migration.
        return props;
    }
0
gene b.