我正在使用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
login-page.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个
答案 0 :(得分:1)
这是从spring security的用户服务中搜索users表。您需要提供与Spring安全性相关的正确配置,或者可以在内存数据库中使用并将某些虚拟用户与角色一起使用。因此,显然这是春季安全配置问题。希望能对您有所帮助。.我现在不在笔记本电脑前,稍后将进行调试和更有价值的发布。
答案 1 :(得分:0)
那是Spring提供的一种魔术。当您使用jdbcAuthentication()
配置Spring安全性时,Spring将使用默认的DaoAuthenticationProvider
来认证传入的请求。您已经创建了自己的User
类,但是Spring无法检测到它,因此它使用JdbcDaoImpl
作为UserDetailsService
的默认实现。
仔细查看源代码会提供以下信息:
默认架构
假定使用默认数据库架构,其中有两个表“ users” 和“当局”。 (Source)
因此,为了使用您自己的实现,您必须提供UserDetailsService
的自定义实现,该实现将从您自己的表中加载用户。