web-dev-qa-db-fra.com

org.postgresql.util.PSQLException: ERREUR: la relation "utilisateur_app" n'existe pas

J'ai une application qui utilise Spring Boot et Postgres. Je reçois cette erreur lorsque j'essaie de créer un utilisateur.

Lorsque j'exécute cette requête sur ma base de données, j'obtiens la même erreur:

select * from APP_USER

ERROR:  relation "app_user" does not exist
LINE 1: select * from APP_USER
                      ^
********** Error **********

ERROR: relation "app_user" does not exist
SQL state: 42P01

Mais si je change cela en:

select * from "APP_USER"

Ça marche.

Comment puis-je configurer cela sur mon application de démarrage de printemps?

dépendances dans pom.xml:

<dependencies>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-tiles2</artifactId>
        <version>2.1.1.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.4-1201-jdbc41</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

</dependencies>

application.properties:

spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/boek
spring.datasource.username=postgres
spring.datasource.password=ABCD123$

spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.generate-ddl=false

#spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true

Mon entité:

@Entity
@Table(name = "APP_USER")
public class User implements Serializable {

    private static final long serialVersionUID = -1152779434213289790L;

    @Id
    @Column(name="ID", nullable = false, updatable = false)
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private long id;

    @Column(name="NAME", nullable = false)
    private String name;

    @Column(name="USER_NAME", nullable = false, unique = true)
    private String username;

    @Column(name="PASSWORD", nullable = false)
    private String password;

    @Column(name="EMAIL", nullable = false, unique = true)
    private String email;

    @Column(name="ROLE", nullable = false)
    private RoleEnum role;

J'appelle cette action depuis un formulaire:

<form role="form" action="#" th:action="@{/user/create}" th:object="${userDTO}" method="post">

et voici mon contrôleur:

@RequestMapping(value = "/user/create", method = RequestMethod.POST)
    public String handleUserCreateForm(@Valid @ModelAttribute("form") UserDTO form, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "user_create";
        }
        try {
            userService.create(form);
        } catch (DataIntegrityViolationException e) {
            bindingResult.reject("email.exists", "Email already exists");
            return "user_create";
        }
        return "redirect:/users";
    }

Le validateur qui a commis l'erreur:

private void validateEmail(Errors errors, UserDTO form) {
        if (userService.getUserByEmail(form.getEmail()).isPresent()) {
            errors.reject("email.exists", "User with this email already exists");
        }
    }

UserServiceImpl (@Service):

@Override
    public Optional<User> getUserByEmail(String email) {
        return userRepository.findOneByEmail(email);
    }

Et le référentiel est une interface CrudRepository, et n’a aucune implémentation:

@Repository
public interface UserRepository extends CrudRepository<User, Serializable> {

    Optional<User> findOneByEmail(String email);
}

Et en déboguant le validateur je pourrais obtenir cette pile:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.Java:238)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.Java:221)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.Java:417)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.Java:59)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.Java:213)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.Java:147)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.Java:122)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.Java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.Java:207)
    at com.Sun.proxy.$Proxy75.findOneByEmail(Unknown Source)
    at com.myapp.service.impl.UserServiceImpl.getUserByEmail(UserServiceImpl.Java:32)
    at com.myapp.model.validator.UserValidator.validateEmail(UserValidator.Java:40)
    at com.myapp.model.validator.UserValidator.validate(UserValidator.Java:30)
    at org.springframework.validation.DataBinder.validate(DataBinder.Java:785)
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.validateIfApplicable(ModelAttributeMethodProcessor.Java:164)
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.Java:111)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.Java:77)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.Java:162)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.Java:129)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.Java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.Java:776)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.Java:705)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.Java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:959)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:893)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:967)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.Java:869)
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:648)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.Java:843)
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:729)
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:291)
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:206)
    at org.Apache.Tomcat.websocket.server.WsFilter.doFilter(WsFilter.Java:52)
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:239)
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:206)
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.Java:295)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107)
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:239)
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:206)
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.Java:102)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107)
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:239)
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:206)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:330)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.Java:118)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.Java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.Java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.Java:103)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.Java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.Java:154)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.Java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.Java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.Java:105)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.Java:57)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.Java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.Java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.Java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.Java:160)
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:239)
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:206)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.Java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107)
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:239)
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.Java:85)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107)
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:239)
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:206)
    at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.Java:68)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107)
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:239)
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:206)
    at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:219)
    at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:106)
    at org.Apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.Java:502)
    at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:142)
    at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:79)
    at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:88)
    at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:518)
    at org.Apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.Java:1091)
    at org.Apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.Java:668)
    at org.Apache.Tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.Java:1521)
    at org.Apache.Tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.Java:1478)
    at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1142)
    at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:617)
    at org.Apache.Tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.Java:61)
    at Java.lang.Thread.run(Thread.Java:745)
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.Java:123)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.Java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.Java:126)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.Java:112)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.Java:91)
    at org.hibernate.loader.Loader.getResultSet(Loader.Java:2066)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.Java:1863)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.Java:1839)
    at org.hibernate.loader.Loader.doQuery(Loader.Java:910)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.Java:355)
    at org.hibernate.loader.Loader.doList(Loader.Java:2554)
    at org.hibernate.loader.Loader.doList(Loader.Java:2540)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.Java:2370)
    at org.hibernate.loader.Loader.list(Loader.Java:2365)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.Java:497)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.Java:387)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.Java:236)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.Java:1300)
    at org.hibernate.internal.QueryImpl.list(QueryImpl.Java:103)
    at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.Java:573)
    at org.hibernate.jpa.internal.QueryImpl.getSingleResult(QueryImpl.Java:495)
    at org.hibernate.jpa.criteria.compile.CriteriaQueryTypeQueryAdapter.getSingleResult(CriteriaQueryTypeQueryAdapter.Java:71)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.Java:202)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.Java:74)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.Java:99)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.Java:90)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.Java:415)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.Java:393)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$DefaultMethodInvokingMethodInterceptor.invoke(RepositoryFactorySupport.Java:506)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.Java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.Java:281)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.Java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.Java:136)
    ... 98 more
Caused by: org.postgresql.util.PSQLException: ERROR: relation "app_user" does not exist
  Posição: 177
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.Java:2270)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.Java:1998)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.Java:255)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.Java:570)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.Java:420)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.Java:305)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.Java:82)
    ... 129 more

Merci pour l'aide!

8
Rafael Lima

PostgreSQL suit le standard SQL et dans ce cas, cela signifie que les identifiants (noms de tables, noms de colonnes, etc.) sont forcés en minuscules, sauf lorsqu'ils sont cités. Alors, quand vous créez une table comme celle-ci:

CREATE TABLE APP_USER ...

vous obtenez réellement une table app_user. Vous avez apparemment fait:

CREATE TABLE "APP_USER" ...

et alors vous obtenez une table "APP_USER".

Au printemps, vous spécifiez une chaîne régulière pour le nom de la table, en lettres majuscules, mais elle est fusionnée en une requête sur le serveur PostgreSQL sans guillemets. Vous pouvez vérifier cela en lisant les fichiers journaux de PostgreSQL: il devrait afficher la requête générée par Spring, suivie de l'erreur en haut de votre message.

Puisque vous avez très peu de contrôle sur la manière dont Spring construit les requêtes des entités, il est préférable d'utiliser des identificateurs de minuscules conformes à la norme SQL.

6
Patrick

La déclaration default schema manquante dans hibernate config pourrait également être causée.

    Properties jpaProperties = new Properties();

    ..

    jpaProperties.put("hibernate.default_schema", "my_default_schema");
    entityManagerFactoryBean.setJpaProperties(jpaProperties);
0
Marcin Szymczak

Cela peut également se produire si votre fichier de mappage n'est pas défini correctement dans le fichier de configuration jpa. Dans mon cas, il y avait un nouveau caractère de ligne avant (balise de fin où le fichier de mappage est défini) dans la configuration jpa.

0
Tushar Patel

Donne le nom du schéma ainsi que le nom de la table . Cela a résolu le problème pour moi.

@Entity
@Table(name = "APP_USER",schema="xxxxx")

public class User implements Serializable {

    private static final long serialVersionUID = -1152779434213289790L;

    @Id
    @Column(name="ID", nullable = false, updatable = false)
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private long id;

    @Column(name="NAME", nullable = false)
    private String name;

    @Column(name="USER_NAME", nullable = false, unique = true)
    private String username;

    @Column(name="PASSWORD", nullable = false)
    private String password;

    @Column(name="EMAIL", nullable = false, unique = true)
    private String email;

    @Column(name="ROLE", nullable = false)
    private RoleEnum role;
0
Ayush Goyal