java - Spring MVC + Hibernate:无法更新实体“加载需要加载的 ID”
问题描述
我有的:
目前我正在使用spring mvc和hibernate开发一个小型银行应用程序。成功登录后,用户被重定向到预览页面,在那里他可以看到存款/取款/查看交易等的所有不同选项。
我的问题是:
输入存款号码并点击提交后,它与标题中的消息一起崩溃。
我认为导致问题的原因是:
我认为这与实体类上的 @Id 注释有关,并且我使用 String(varchar) 作为主键,尽管我不太确定。任何帮助都会受到好评,请在下面添加我的代码。
package nselect.BankingApp.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import nselect.BankingApp.entities.Users;
import nselect.BankingApp.services.UsersService;
/**
* Controller for the inner part of the app, meaning after the user logins
*
* @author Asus
*
*/
@Controller
@RequestMapping("/home")
public class MainController {
@Autowired
UsersService usersService;
@RequestMapping("/preview")
public String getMainView(Model model, @ModelAttribute ("user") Users user) {
double currentBalance = user.getAccBalance();
model.addAttribute("balance", currentBalance);
return "preview";
}
@RequestMapping("/preview/deposit")
public String returnDepositForm() {
return "depositForm";
}
@RequestMapping("/preview/deposit/depositConfirmation")
public String deposit(HttpServletRequest request, @ModelAttribute ("user") Users user) {
Users currentUser = usersService.findByUsername(user.getUsername());
double deposit_amount = Double.parseDouble(request.getParameter("deposit_amount"));
currentUser.setAccBalance(deposit_amount);
usersService.update(currentUser);
return "deposit_confirmation";
}
@RequestMapping("/preview/withdraw")
public String withdraw() {
return null;
}
@RequestMapping("/preview/viewTransactions")
public String viewTransactions() {
return null;
}
@RequestMapping("/preview/transfer")
public String transfer() {
return null;
}
}
实体类:
package nselect.BankingApp.entities;
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 class for all the users in the app
* @author Asus
*
*/
@Entity
@Table(name="users")
public class Users {
@Id
//@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="username")
private String username;
@Column(name="password")
private String password;
@Column(name="acc_balance")
private double accBalance;
@Column(name="email")
private String email;
public Users() {
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public double getAccBalance() {
return accBalance;
}
public String getEmail() {
return email;
}
public void setAccBalance(double accBalance) {
this.accBalance = accBalance;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Users [username=" + username + ", password=" + password + ", accBalance=" + accBalance + ", email="
+ email + "]";
}
}
服务等级:
package nselect.BankingApp.services;
import java.util.List;
import org.springframework.stereotype.Service;
import nselect.BankingApp.dao.GenericDao;
import nselect.BankingApp.dao.UsersDao;
import nselect.BankingApp.entities.Users;
@Service
public class UsersService implements GenericDao<Users> {
private UsersDao usersDao;
public UsersService() {
this.usersDao = new UsersDao();
}
@Override
public void persist(Users entity) {
usersDao.openCurrentSessionWithTransaction();
usersDao.persist(entity);
usersDao.closeCurrentSessionWithTransaction();
}
@Override
public void update(Users entity) {
usersDao.openCurrentSessionWithTransaction();
usersDao.update(entity);
usersDao.closeCurrentSessionWithTransaction();
}
/**
* Not being used, just a implementation of the interface method
*/
@Override
public Users findByID(int id) {
return null;
}
public Users findByUsername(String username) {
usersDao.openCurrentSession();
Users user = usersDao.findByUsername(username);
usersDao.closeCurrentSession();
return user;
}
@Override
public void delete(Users entity) {
// TODO Auto-generated method stub
}
@Override
public List<Users> findAll() {
usersDao.openCurrentSessionWithTransaction();
List<Users> users = usersDao.findAll();
usersDao.closeCurrentSessionWithTransaction();
return users;
}
}
道:
package nselect.BankingApp.dao;
import java.util.List;
import nselect.BankingApp.entities.Users;
public class UsersDao extends SessionTransactionControl implements GenericDao<Users> {
@Override
public void persist(Users entity) {
super.getCurrentSession().save(entity);
}
@Override
public void update(Users entity) {
super.getCurrentSession().saveOrUpdate(entity);
}
@Override
public Users findByID(int id) {
// TODO Auto-generated method stub
return null;
}
public Users findByUsername(String username) {
Users user = super.currentSession.find(Users.class, username);
return user;
}
@Override
public void delete(Users entity) {
// TODO Auto-generated method stub
}
@Override
public List<Users> findAll() {
List<Users> users = super.getCurrentSession().createQuery("from Users u").getResultList();
return users;
}
}
JSP:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Deposit money</title>
</head>
<body>
<form action="deposit/depositConfirmation">
Amount you want to deposit: <input type="text" name="deposit_amount">
<input type="submit" value="Deposit">
</form>
</body>
</html>
MySQL 表:
CREATE TABLE `users` (
`username` VARCHAR(40) NOT NULL,
`password` VARCHAR(70) NOT NULL,
`acc_balance` DECIMAL(6,2) NOT NULL,
`email` VARCHAR(40) NULL DEFAULT NULL,
PRIMARY KEY (`username`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;
从Tomcat:
SEVERE: Servlet.service() for servlet [SpringDispatcher] in context with path [/BankingApp] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: id to load is required for loading] with root cause
java.lang.IllegalArgumentException: id to load is required for loading
at org.hibernate.event.spi.LoadEvent.<init>(LoadEvent.java:96)
at org.hibernate.event.spi.LoadEvent.<init>(LoadEvent.java:64)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.doLoad(SessionImpl.java:2773)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.lambda$load$1(SessionImpl.java:2757)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.perform(SessionImpl.java:2713)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2757)
at org.hibernate.internal.SessionImpl.find(SessionImpl.java:3312)
at org.hibernate.internal.SessionImpl.find(SessionImpl.java:3274)
at nselect.BankingApp.dao.UsersDao.findByUsername(UsersDao.java:29)
at nselect.BankingApp.services.UsersService.findByUsername(UsersService.java:49)
at nselect.BankingApp.controller.MainController.deposit(MainController.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
解决方案
推荐阅读
- r - Count occurrences of elements in a vector that occur in another vector
- php - PAYPAL php SDK1.0.1, how to set NO_SHIPPING
- visual-studio - Visual Studio SSIS 项目的版本控制
- javascript - 如何单独获取数组的每个值并在其上运行具有未知数量值的函数
- php - 多次 ajax 调用后未保留 WooCommerce 会话数据
- docker - Docker - 带有 php-fpm 连接的 nginx 被拒绝
- crystal-reports - 使用 Crystal Reports 连接到 Snowflake
- r - 逻辑回归错误:y 值必须为 0 <= y <= 1
- sql - SQL Server 2016 SP1:日期函数错误 - 以前有人遇到过这个问题吗?
- google-cloud-platform - 从运行在 Google Cloud VM 实例上的应用程序访问 Google Secrets - 将 Cloud API 分配给 VM