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