PSQLException: 错误:关系"TABLE_NAME"不存在。

43

我正在尝试在PostgreSQL 8.4.2数据库上运行Hibernate。每当我尝试运行一个简单的Java代码,例如:

List<User> users = service.findAllUsers();

我遇到了以下错误:

PSQLException: ERROR: relation "TABLE_NAME" does not exist

由于我已经设置了hibernate.show_sql选项为true,因此可以看到Hibernate正在尝试运行以下SQL命令:

    select this_.USERNAME as USERNAME0_0_, this_.PASSWORD as PASSWORD0_0_ 
from "TABLE_NAME" this_

实际上,它至少应该运行类似于以下的东西:

    select this_."USERNAME" as USERNAME0_0_, this_."PASSWORD" as PASSWORD0_0_ 
from "SCHEMA_NAME"."TABLE_NAME" as this_

有人知道我需要做哪些更改,才能让Hibernate生成适用于PostgreSQL的正确SQL语句吗?

我已经在applicationContext.xml文件中设置了必要的PostgreSQL数据源:

<!-- Use Spring annotations -->
 <context:annotation-config /> 
 <!-- postgreSQL datasource -->
 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
  destroy-method="close">
  <property name="driverClassName" value="org.postgresql.Driver" />
  <property name="url"
   value="jdbc:postgresql://localhost/DB_NAME:5432/SCHEMA_NAME" />
  <property name="username" value="postgres" />
  <property name="password" value="password" />
  <property name="defaultAutoCommit" value="false" />
 </bean>

在同一个文件中,我已经使用PostgreSQL方言设置了会话工厂:

<!-- Hibernate session factory -->
 <bean id="sessionFactory"   class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="annotatedClasses">
   <list>
    <value>com.myPackage.dbEntities.domain.User</value>
   </list>
  </property>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
    <prop key="hibernate.show_sql">true</prop>
   </props>
  </property>
 </bean>
 <!-- setup transaction manager -->
 <bean id="transactionManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory">
   <ref bean="sessionFactory" />
  </property>
 </bean>

最后,我将域类映射到表的方式如下:

    @Entity
@Table(name = "`TABLE_NAME`")
public class User {
@Id
@Column(name = "USERNAME")
private String username;

有人遇到类似的错误吗?非常感谢任何帮助解决此问题的帮助。 请注意,这个问题与Cannot simply use PostgreSQL table name (”relation does not exist”)不同。

对于冗长的帖子表示歉意。


1
只是问一个显而易见的问题:访问数据库的用户帐户是否具有查看TABLE_NAME表的权限?(如果您在连接中指定了模式,则可以省略Hibernate选择中的模式名称)。 - davek
是的,在该表上有以下权限:ALTER TABLE "SCHEMA_NAME"."TABLE_NAME" OWNER TO postgres; - Lucas T
6个回答

30

您需要在Spring的Hibernate属性中指定模式名称,而不是在JDBC连接URL中指定:

<prop key="hibernate.default_schema">SCHEMA_NAME</prop>

话虽如此,您的JDBC连接URL实际上是语法无效的。根据PostgreSQL JDBC文档,您必须使用以下语法之一:

  • jdbc:postgresql:database
  • jdbc:postgresql://host/database
  • jdbc:postgresql://host:port/database

这里的database是数据库名称。如果省略主机,则默认为localhost。如果省略端口号,则默认为5432。因此,在您的情况下,以下其中之一是有效的:

  • jdbc:postgresql:DB_NAME
  • jdbc:postgresql://localhost/DB_NAME
  • jdbc:postgresql://localhost:5432/DB_NAME

我会立即尝试您的解决方案,BalusC。我假设连接URL是有效的,因为我使用它来测试postgresql-8.4-701.jdbc4.jar驱动程序和SQuirrel SQL客户端中的DB连接。 - Lucas T
1
架构名称区分大小写,不应包含空格或其他特殊字符。 - BalusC
我知道模式是区分大小写的。这就是为什么我想知道为什么Hibernate显示这样的错误消息,但在实际的SQL命令中它使用大写模式。谢谢你的帮助。 - Lucas T
根据我之前发布的评论:“ERROR: schema "schema_name" does not exist”,我遇到这个问题的原因是模式名称为SCHEMA_NAME(全部大写),而hibernate会将名称转换为小写。我采用了BalusC建议的解决方案,强制hibernate接受大写名称。我使用了"而不是推荐的'符号:<prop key="hibernate.default_schema">"SCHEMA_NAME"</prop>。最终问题得以解决。我从https://forum.hibernate.org/viewtopic.php?f=1&t=935715&p=2416841获取了解决方案。 - Lucas T
1
在我的 X.hbm.xml 文件中,我从 <class name="com.mycompany.app.common.Stock" table="stock"> 中移除了一个无效的 class="..." 属性,以解决我的问题。 - Kevin Meredith
显示剩余5条评论

5
如果您正在使用spring-boot,可以在配置文件中设置默认的数据库模式(schema):
spring.jpa.properties.hibernate.default_schema: my_schema

请确保在查询中包含模式名称:

@Query(value = "SELECT user_name FROM my_schema.users", nativeQuery = true)
List<String> findAllNames();

我的问题是我使用了jpa.properties.hibernate: default-schema而不是default_schema(default-schemadefault_schema)。 _ - Dmitry Kaltovich

1
由于使用列定义,我遇到了这个错误。
问题 @Column(name = "user_id", nullable = false, unique = true, columnDefinition ="user unique ID" )
解决 @Column(name = "user_id", nullable = false, unique = true)
谢谢。

1

看了一下PostgreSQL JDBC驱动程序的文档,似乎不支持在连接URL的末尾添加模式。你确定这样做是可以的吗?

一个解决方法是将数据库中的search_path设置为包括您的模式,但如果您在多个模式中具有相同的表,则显然会失败。

我不太了解Hibernate,无法评论它是否可以学习有关模式的知识。


1
是的,我已经使用postgresql-8.4-701.jdbc4.jar驱动程序测试了连接,并且我确实使用了该URL(jdbc:postgresql://localhost/DB_NAME:5432/SCHEMA_NAME)成功连接到数据库。由于我只在postgres中使用一个模式,所以我会看看如何使用search_path。 - Lucas T
请再检查一遍,http://jdbc.postgresql.org/documentation/84/connect.html 上的文档甚至没有提到模式。 - Milen A. Radev
感谢Milen和BalusC指出问题。我对postgres比较陌生,虽然我已经阅读了文档,但在测试驱动程序时连接URL是有效的,因此我认为它是正确的。现在似乎出现了不同类型的错误。 - Lucas T

1
在我的情况下,模式名称是大写的,我将模式名称改为小写。
在实体中,我更改了映射,如下所示:
从 @Table(name="table_name", schema = "SCHEMA") 到 @Table(name="table_name", schema = "schema")

1

不确定其他人是否一样,但我的情况只有在我像这样编写查询时才起作用:

@Query(value = "SELECT tbl.* FROM my_schema.my_table tbl", nativeQuery = true)

始终为表格准备一个参考“tbl”,并在查询中使用它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接