41

I am trying to run hibernate on a PostgreSQL 8.4.2 DB. Whenever I try to run a simple java code like:

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

I get the following error:

PSQLException: ERROR: relation "TABLE_NAME" does not exist

Since I have option hibernate.show_sql option set to true, I can see that hibernate is trying to run the following SQL command:

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

When in reality, it should at least run something like:

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

Does anyone know what changes I need to make for Hibernate to produce the right SQL for PostgreSQL?

I have set up the necessary postgreSQL datasource in applicationContext.xml file:

<!-- 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>

On the same file I have set up the session factory with PostgreSQL dialect:

<!-- 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>

Finally, the way I am mapping the domain class to the table is:

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

Has anyone encountered a similar error?. Any help in solving this issue will be much appreciated. Please note that question is different to post Cannot simply use PostgreSQL table name (”relation does not exist”)

Apologies for the lengthy post.

Community
  • 1
  • 1
Lucas T
  • 3,011
  • 6
  • 29
  • 36
  • 1
    just to ask the obvious: does the user account accessing the database have permissions to view table TABLE_NAME? (if you have specified the schema in the connection it may not be wrong to omit the schema name from the hibernate select). – davek Jan 09 '10 at 17:18
  • Yes, I on the table there is the following permission: ALTER TABLE "SCHEMA_NAME"."TABLE_NAME" OWNER TO postgres; – Lucas T Jan 09 '10 at 18:19

6 Answers6

29

You need to specify the schema name in the Spring's Hibernate properties, not in the JDBC connection URL:

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

That said, your JDBC connection URL is in fact syntactically invalid. According to the PostgreSQL JDBC documentation you have to use one of the following syntaxes:

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

The database is here the database name. If the host is left away, it will default to localhost. If the port number is left away, it will just default to 5432. Thus, one of the following is valid in your case:

  • jdbc:postgresql:DB_NAME
  • jdbc:postgresql://localhost/DB_NAME
  • jdbc:postgresql://localhost:5432/DB_NAME
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I'll try your solution straight away, BalusC. I assumed the connection URL was valid since I used it to test the connection to DB with the postgresql-8.4-701.jdbc4.jar driver and also in SQuirrel SQL Client. – Lucas T Jan 09 '10 at 18:43
  • If the prefix (in this case `jdbc:postgresql`) is valid, then the Driver will often not throw a `SQLException` for that, but the trailing part of your original URL is syntactically invalid. You shouldn't rely on the forgiveness of the drivers for that. – BalusC Jan 09 '10 at 18:45
  • I have tried your suggestion for db URL connection and it seems to work. I now get a different type of error: PSQLException: ERROR: schema "schema_name" does not exist. And hibernate created the following statement:select this_.USERNAME as USERNAME0_0_, this_.PASSWORD as PASSWORD0_0_ from SCHEMA_NAME."TABLE_NAME" this_ . I can only assume that your suggested solution did indeed solve the problem and there is just another problem to solve. – Lucas T Jan 09 '10 at 19:01
  • 1
    Schema name is case sensitive and should not contain spaces or other special characters. – BalusC Jan 09 '10 at 19:26
  • I am aware of schema being case sensitive. That's why I wonder why hibernate displays such error message but on actual SQL command it uses schema in upper case. Thanks for your help, though – Lucas T Jan 09 '10 at 19:31
  • Maybe you connected the wrong DB or the schema name is actually wrong (typo?). – BalusC Jan 09 '10 at 19:33
  • No, I'm afraid that is the only DB on localhost, and the only schema on the DB. Thanks, nonetheless. – Lucas T Jan 09 '10 at 19:41
  • I have, that's where I got the schema name from. Thanks once again. – Lucas T Jan 09 '10 at 19:56
  • following the earlier comment I posted:"ERROR: schema "schema_name" does not exist", the reason why I got that was because schema was called SCHEMA_NAME (all in upper case) and hibernate would make the name lowercase. The way I got around it was to use BalusC suggested solution and to force hibernate to accept the upper case name. I added " instead of the recommended ' sign: "SCHEMA_NAME". That finally solved the problem. I got the solution from https://forum.hibernate.org/viewtopic.php?f=1&t=935715&p=2416841 – Lucas T Jan 15 '10 at 21:58
  • 1
    In my `X.hbm.xml` file, I removed an invalid `class="..."` attribute from `` to resolve my problem. – Kevin Meredith Jan 25 '14 at 04:14
5

If you are using spring-boot, set default schema in the configuration:

spring.jpa.properties.hibernate.default_schema: my_schema

Make sure to include the schema name in the query:

@Query(value = "SELECT user_name FROM my_schema.users", nativeQuery = true)
List<String> findAllNames();
Shripad Bhat
  • 2,373
  • 2
  • 19
  • 21
  • My problem was that I used `jpa.properties.hibernate: default-schema` insted of `default_schema` (`default-schema` vs `default_schema`). `_` – Dmitry Kaltovich Sep 04 '22 at 17:26
1

Looking at the PostgreSQL JDBC driver documentation, it doesn't seem to support you adding the schema at the end of the connection url. Are you sure that's supposed to work?

A workaround would be to set the search_path in the database to include your schema, but that would obviously fail if you have the same table in multiple schemas.

I don't know hibernate enough to comment on if it's possible to teach it about a schema.

Magnus Hagander
  • 23,890
  • 5
  • 56
  • 43
  • 1
    Yes, I have tested the connection using postgresql-8.4-701.jdbc4.jar driver and I did use that URL (jdbc:postgresql://localhost/DB_NAME:5432/SCHEMA_NAME) to make a successful connection to the DB. I'll see how to use the search_path since I'm only using one schema in postgres. – Lucas T Jan 09 '10 at 18:38
  • Check again, the docs at http://jdbc.postgresql.org/documentation/84/connect.html don't even mention schema. – Milen A. Radev Jan 09 '10 at 18:49
  • Thank, Milen. BalusC pointed that out. I am new to postgres and although I have read the documentation, the connection url worked when testing the driver so I assumed it was correct. I now seem to have a different type of error. – Lucas T Jan 09 '10 at 19:08
1

Due to using column definations I was getting this error

issue @Column(name = "user_id", nullable = false, unique = true, columnDefinition ="user unique ID" )

solved @Column(name = "user_id", nullable = false, unique = true)

Thanks

Shahid Hussain Abbasi
  • 2,508
  • 16
  • 10
1

Not sure about others but my case if worked only if I wrote my query like this:

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

Always have some reference "tbl" for table and use it in the query.

Indrajeet Gour
  • 4,020
  • 5
  • 43
  • 70
1

In my case I had the schema name in uppercase letters, I changed the schema name to lowercase letters.

In the entities I changed the mapping as follows

from @Table(name="table_name", schema = "SCHEMA") to @Table(name="table_name", schema = "schema")