Java Spring 表不存在

Posted

技术标签:

【中文标题】Java Spring 表不存在【英文标题】:Java Spring table doesn't exist 【发布时间】:2019-03-25 07:29:01 【问题描述】:

我正在使用 Spring 和 Hibernate 编写一个 Web 应用程序,但第一次遇到这种问题。每当我在服务器上运行我的应用程序时,它都会显示**“java.sql.SQLSyntaxErrorException:表'restaurantapp.users'不存在。”**我不明白的是我什至没有表在我的数据库中称为“用户”,而且我从未在我的应用程序中使用过表“用户”。代码部分如下。需要帮助来解决这个问题。

实体类:

package com.jafndy.Restaurant.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="admin_login")
public class RestaurantAdmin 

@Id
@Column(name="user_id")
@GeneratedValue(strategy=GenerationType.AUTO)
private int user_id;

@Column(name="username")
private String username;

@Column(name="authority")
private String authority;

@Column(name="email")
private String email;

@Column(name="password")
private String password;

public RestaurantAdmin(int user_id, String username, String authority, 
String email, String password) 
    super();
    this.user_id = user_id;
    this.username = username;
    this.authority = authority;
    this.email = email;
    this.password = password;


public RestaurantAdmin() 



public int getUser_id() 
    return user_id;


public void setUser_id(int user_id) 
    this.user_id = user_id;


public String getUsername() 
    return username;


public void setUsername(String username) 
    this.username = username;


public String getAuthority() 
    return authority;


public void setAuthority(String authority) 
    this.authority = authority;


public String getEmail() 
    return email;


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


public String getPassword() 
    return password;


public void setPassword(String password) 
    this.password = password;


@Override
public String toString() 
    return "RestaurantAdmin [user_id=" + user_id + ", username=" + username + ", authority=" + authority
            + ", email=" + email + ", password=" + password + "]";

配置类:

package com.jafndy.Restaurant.config;

import java.beans.PropertyVetoException;
import java.util.Properties;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import com.mchange.v2.c3p0.ComboPooledDataSource;

@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan(basePackages="com.jafndy.Restaurant")
@PropertySource("classpath:persistence-mysql.properties")
public class AppConfig 

//set up variable to hold variables
@Autowired
private Environment env;

//define a bean for the view resolver
@Bean
public ViewResolver viewResolver() 
    InternalResourceViewResolver viewResolver = new             
InternalResourceViewResolver();

    viewResolver.setPrefix("/WEB-INF/view/");
    viewResolver.setSuffix(".jsp");

    return viewResolver;


//define a bean for security datasource
@Bean
public DataSource securityDataSource() 
    //create a connection pool
    ComboPooledDataSource securityDataSource = new ComboPooledDataSource();

    //set the jdbc driver class
    try 
        securityDataSource.setDriverClass(env.getProperty("jdbc.driver"));
    catch(PropertyVetoException exc)
        throw new RuntimeException();
    

    //set database connection properties
    securityDataSource.setJdbcUrl(env.getProperty("jdbc.url"));
    securityDataSource.setUser(env.getProperty("jdbc.user"));
    securityDataSource.setPassword(env.getProperty("jdbc.password"));

    //set connection pool properties

securityDataSource.setInitialPoolSize(getIntProperty("connection.pool.initialPoolSize")); securityDataSource.setMinPoolSize(getIntProperty("connection.pool.minPoolSize")); securityDataSource.setMaxPoolSize(getIntProperty("connection.pool.maxPoolSize")); securityDataSource.setMaxIdleTime(getIntProperty("connection.pool.maxIdleTime"));

    return securityDataSource;


//define a bean for Hibernate
@Bean
public LocalSessionFactoryBean sessionFactory() 
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();

    sessionFactory.setDataSource(securityDataSource());
    sessionFactory.setPackagesToScan("com.jafndy.Restaurant.entity");
    sessionFactory.setHibernateProperties(hibernateProperties());

    return sessionFactory;


@Bean
public PlatformTransactionManager hibernateTransactionManager() 
    HibernateTransactionManager transactionManager = new HibernateTransactionManager();

    transactionManager.setSessionFactory(sessionFactory().getObject());

    return transactionManager;


private final Properties hibernateProperties() 
    Properties hibernateProperties = new Properties();

    hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
    hibernateProperties.setProperty("hibernate.show_sql", "true");

    return hibernateProperties;


//helper method
//read environment property and convert it to int
private int getIntProperty(String propName) 

    String propValue = env.getProperty(propName);
    int intPropValue = Integer.parseInt(propValue);

    return intPropValue;
   





package com.jafndy.Restaurant.config;

import 

org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class MySpringMvcDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer 

@Override
protected Class<?>[] getRootConfigClasses() 
    // TODO Auto-generated method stub
    return null;


@Override
protected Class<?>[] getServletConfigClasses() 
    // TODO Auto-generated method stub
    return new Class[] AppConfig.class;


@Override
protected String[] getServletMappings() 
    // TODO Auto-generated method stub
    return new String[] "/";

package com.jafndy.Restaurant.config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 

//add a reference to our security DataSource
@Autowired
private DataSource securityDataSource;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception         
    auth.jdbcAuthentication().dataSource(securityDataSource);


@Override
protected void configure(HttpSecurity http) throws Exception 

    http.authorizeRequests()
        .antMatchers("/").hasAnyRole("CUSTOMER","ADMIN")
        .antMatchers("/systems/**").hasRole("ADMIN")
    .and()
    .formLogin()
        .loginPage("/login")
        .loginProcessingUrl("/authenticateUser")
        .permitAll()
    .and()
        .logout()
        .permitAll()
    .and()
        .exceptionHandling().accessDeniedPage("/access-denied");








package com.jafndy.Restaurant.config;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer 

控制器类:

package com.jafndy.Restaurant.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class RestaurantControllerLogin 

@GetMapping("/login")
public String loginPage() 
    return "login-page";





package com.jafndy.Restaurant.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class RestaurantController 

@GetMapping("/")
public String showHome() 
    return "home";



persistence-mysql.properties 文件

#
# JDBC connection libraries
#
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/restaurantapp?useSSL=false
jdbc.user=restaurant
jdbc.password=restaurant_1_2_3

#
# Connection pool properties
#
connection.pool.initialPoolSize=5
connection.pool.minPoolSize=5
connection.pool.maxPoolSize=20
connection.pool.maxIdleTime=3000

#
# Setup Hibernate session factory
#
hibernate.packagesToScan=com.jafndy.Restaurant.entity

登录页面.jsp

<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
    <style>
        .error
            color: red;
        
        .logout
            color: green;
        
    </style>
</head>
<body>
    <h2>Restaurant Login</h2>
    <form:form action="$pageContext.request.contextPath/authenticateUser" 
method="POST">
        <c:if test="$param.error != null ">
            <b class="error">Invalid username or password</b>
        </c:if>
        <c:if test="$param.logout != null ">
            <i class="logout">You've been logged out</i>
        </c:if>
        <p>
            Username: <input type="text" name="username"/>
        </p>
        <p>
            Password: <input type="password" name="password"/>
        </p>
        <input type="submit" value="Log in"/>
    </form:form>
</body>
</html>

home.jsp

<!DOCTYPE html>
<html>
<head>
    <style>
        h1
            display: none;
        
    </style>
</head>
<body>
    <h1 id="h1hidden"></h1>
    <button 
onclick="document.getElementById('h1hidden').style.display='block'">Click to 
see</button>
</body>
</html>

还有我的错误日志

org.springframework.security.authentication.InternalAuthenticationServiceException: PreparedStatementCallback;错误的 SQL 语法 [选择用户名,密码,从用户名 = ?的用户中启用];嵌套异常是 java.sql.SQLSyntaxErrorException:表 'restaurantapp.users' 不存在 在 org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:119) 在 org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:144) 在 org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174) 在 org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199) 在 org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94) 在 org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 在 org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 在 org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:124) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 在 org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 在 org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 在 org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 在 org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) 在 org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) 在 org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) 在 org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) 在 org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) 在 org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) 在 org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) 在 org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770) 在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) 在 org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(未知来源) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(未知来源) 在 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 在 java.lang.Thread.run(未知来源) 引起:org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback;错误的 SQL 语法 [选择用户名,密码,从用户名 = ?的用户中启用];嵌套异常是 java.sql.SQLSyntaxErrorException:表 'restaurantapp.users' 不存在 在 org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:235) 在 org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) 在 org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1402) 在 org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:620) 在 org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:657) 在 org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:688) 在 org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:700) 在 org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:751) 在 org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.loadUsersByUsername(JdbcDaoImpl.java:227) 在 org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.loadUserByUsername(JdbcDaoImpl.java:184) 在 org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:104) ... 42 更多 引起:java.sql.SQLSyntaxErrorException:表'restaurantapp.users'不存在 在 com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:118) 在 com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:95) 在 com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) 在 com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:960) 在 com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1019) 在 com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76) 在 org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:666) 在 org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:605) ... 49 更多

【问题讨论】:

【参考方案1】:

这是从spring security的用户服务中搜索users表。您需要提供与 Spring Security 相关的正确配置,或者您可以在内存数据库中使用一些虚拟用户以及角色。所以显然这是弹簧安全配置问题的问题。希望对您有所帮助.. 我现在不在笔记本电脑前,稍后将调试并发布更多宝贵信息。

【讨论】:

【参考方案2】:

这就是 Spring 提供的魔法。当您使用 jdbcAuthentication() 配置 Spring 安全性时,Spring 将使用默认的 DaoAuthenticationProvider 来验证传入请求。您已经创建了自己的 User 类,但 Spring 无法检测到它,因此它使用 JdbcDaoImpl 作为 UserDetailsService 的默认实现。

仔细查看源代码可以得到以下信息:

默认架构

假设默认数据库架构,有两个表“用户” 和“当局”。 (Source)

因此,为了使用您自己的实现,您必须提供UserDetailsService 的自定义实现,它会从您自己的表中加载用户。

【讨论】:

以上是关于Java Spring 表不存在的主要内容,如果未能解决你的问题,请参考以下文章

插入表,如果表不存在,则创建表然后插入

JavaFX CSS 错误(属性样式表不存在)

如果表不存在,如何使用 Derby Db 创建表

java连接oracle数据库,显示表或视图不存在

Spring boot 报错:Spring table 不存在

如果表不存在,如何选择不出错