'JPA ERROR: relation does not exist

I can't figure out what I'm doing wrong. I'm learning JPA mapping to a relational DB, by following some tutorials on the web, but can't find one that is straightforward. When I run my project, it gives me an error. I guess it's upon persisting em.persist();. If I comment that line, all looks good, and no errors, but no data is written to table, obviously. Here's my code:

persistence.xml (generated, untouched)

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="RESTappPU" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>restapp.entities.ContactList</class>
        <properties>
            <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/postgres"/>
            <property name="javax.persistence.jdbc.user" value="postgres"/>
            <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
            <property name="javax.persistence.jdbc.password" value="postgres"/>
        </properties>
    </persistence-unit>
</persistence>

Entity Class(generated, untouched) - Do I need to add some additional 'relation' method here?

package restapp.entities;

imports [...]

@Entity
@Table(name = "ContactList")
@NamedQueries({
    @NamedQuery(name = "ContactList.findAll", query = "SELECT c FROM ContactList c"),
    @NamedQuery(name = "ContactList.findByFirstname", query = "SELECT c FROM ContactList c WHERE c.firstname = :firstname"),
    @NamedQuery(name = "ContactList.findByLastname", query = "SELECT c FROM ContactList c WHERE c.lastname = :lastname"),
    @NamedQuery(name = "ContactList.findByMobile", query = "SELECT c FROM ContactList c WHERE c.mobile = :mobile"),
    @NamedQuery(name = "ContactList.findByEmail", query = "SELECT c FROM ContactList c WHERE c.email = :email")})
public class ContactList implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "firstname")
    private String firstname;
    @Column(name = "lastname")
    private String lastname;
    @Basic(optional = false)
    @Column(name = "mobile")
    private String mobile;
    @Column(name = "email")
    private String email;

    // constructors
    public ContactList() {
    }

    public ContactList(String firstname) {
        this.firstname = firstname;
    }

    public ContactList(String firstname, String mobile) {
        this.firstname = firstname;
        this.mobile = mobile;
    }

    public ContactList(String firstname, String lastname, String mobile, String email) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.mobile = mobile;
        this.email = email;
    }

    // getter's and setter's
    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    // Is something like this what it needs?
    //    @OneToOne(cascade=CascadeType.PERSIST)
    //    private Address address;

    //    @OneToMany(cascade=ALL, mappedBy="customer")
    //    public Collection<Order> getOrders() {
    //        return orders;
    //    }


    @Override
    public String toString() {
        return "\n\n\n\n[firstname: " + firstname + "]\n"
                + "[lastname: " + lastname + "]\n"
                + "[mobile: " + mobile + "]\n"
                + "[email: " + email + "]\n\n\n\n";
    }

}

Java App Class

package restapp;

imports [...]

public class RESTapp {

    private static EntityManagerFactory emf;
    private static EntityManager em;

    public static void main(String[] args) {
        // Create EntityManagerFactory for persistent unit named "pu1" to be used in this test
        emf = Persistence.createEntityManagerFactory("RESTappPU");

        // Persist the customer
        // em.persist(list0);
        // Persist all entities
        createTransactionalEntityManager();
        System.out.println("Inserting Customer and Orders... " + insert());
        closeTransactionalEntityManager();
    }

    private static String insert() {
        // Create new contact
        ContactList list0 = new ContactList();
        list0.setFirstname("John");
        list0.setLastname("Doe");
        list0.setMobile("+351 91 546 33 21");
        list0.setEmail("[email protected]");

        // Create another contact
        ContactList list1 = new ContactList("Jane", "Something", "+351 96 924 14 29", "[email protected]");

        list0.toString();

//        em.persist(list0);
        em.persist(list0);

        return "OK";
    }

    private static void createTransactionalEntityManager() {

        // Create a new EntityManager
        em = emf.createEntityManager();

        // Begin transaction
        em.getTransaction().begin();
    }

    private static void closeTransactionalEntityManager() {

        // Commit the transaction
        em.getTransaction().commit();

        // Close this EntityManager
        em.close();
    }
}

And when I run my project:

run:
[EL Info]: 2015-06-03 18:30:17.315--ServerSession(1798636297)--EclipseLink, version: Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd
[EL Info]: connection: 2015-06-03 18:30:17.689--ServerSession(1798636297)--file:/home/rsousa/NetBeansProjects/RESTapp/build/classes/_RESTappPU login successful
Inserting Customer and Orders... OK
[EL Warning]: 2015-06-03 18:30:17.794--UnitOfWork(683523720)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: relation "contactlist" does not exist
  Position: 13
Error Code: 0
Call: INSERT INTO ContactList (firstname, email, lastname, mobile) VALUES (?, ?, ?, ?)
    bind => [4 parameters bound]
Query: InsertObjectQuery(



[firstname: John]
[lastname: Doe]
Exception in thread "main" javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
[mobile: +351 91 546 33 21]
Internal Exception: org.postgresql.util.PSQLException: ERROR: relation "contactlist" does not exist
[email: [email protected]]



)
  Position: 13
Error Code: 0
Call: INSERT INTO ContactList (firstname, email, lastname, mobile) VALUES (?, ?, ?, ?)
    bind => [4 parameters bound]
Query: InsertObjectQuery(



[firstname: John]
[lastname: Doe]
[mobile: +351 91 546 33 21]
[email: [email protected]]



)
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:157)
    at restapp.RESTapp.closeTransactionalEntityManager(RESTapp.java:66)
    at restapp.RESTapp.main(RESTapp.java:32)
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: relation "contactlist" does not exist
  Position: 13
Error Code: 0
Call: INSERT INTO ContactList (firstname, email, lastname, mobile) VALUES (?, ?, ?, ?)
    bind => [4 parameters bound]
Query: InsertObjectQuery(



[firstname: John]
[lastname: Doe]
[mobile: +351 91 546 33 21]
[email: [email protected]]



)
    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:340)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processExceptionForCommError(DatabaseAccessor.java:1611)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:898)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:962)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:631)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
    at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2002)
    at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:298)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:377)
    at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:165)
    at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:180)
    at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:489)
    at org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:80)
    at org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:90)
    at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:301)
    at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
    at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:798)
    at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
    at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1786)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1737)
    at org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:226)
    at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:125)
    at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:4207)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1441)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531)
    at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:277)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169)
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132)
    ... 2 more
Caused by: org.postgresql.util.PSQLException: ERROR: relation "contactlist" does not exist
  Position: 13
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2157)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1886)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:555)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:417)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:363)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:890)
    ... 33 more
Java Result: 1
BUILD SUCCESSFUL (total time: 3 seconds)

IDE: NetBeans | DB: PostGreSQL | Persistence: EclipseLink JPA



Solution 1:[1]

Postgresql converts table and column names which are not double quoted to lower case. Change

@Table(name = "ContactList")

to

@Table(name = "contactlist")

Solution 2:[2]

In my case, the problem was not precised schema- which can be provided in annotation over class:

@Table(name="...", schema="...")

Solution 3:[3]

You can use this config in application.properties:

spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

Solution 4:[4]

I had a similar problem, but in my case, in the query I had to prefix the table names with the schema name as my DB has multiple schemas and I was using a native query.

Solution 5:[5]

I had a similar problem but using @Query annotation.

I solved it by specifying [?currentSchema=public] at the end of the connection URL in the wildfly server datasource:

jdbc:postgresql://myhost:5432/mydatabase?currentSchema=public

This set the default schema at database user login and makes the table to be discovered.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sarit Adhikari
Solution 2 Krystian
Solution 3 Vu Ruby
Solution 4 Russ Jackson
Solution 5 Francisco M