首页 > 解决方案 > 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)

标签: javamysqlhibernatespring-mvcjsp

解决方案


推荐阅读