【问题标题】:JavaEE does not throw SQLException when primary key is duplicated主键重复时 JavaEE 不抛出 SQLException
【发布时间】:2021-03-14 15:09:14
【问题描述】:

我正在学习使用 JavaEE(不是 SPRING)的 Java Web 应用程序。但是我遇到了一个问题,当使用重复的主键将一行插入到表中时,我的应用程序不会抛出SQLException

详细来说,我有一个带有createNewAccount 方法的DAO 类AccountInfoDAO.java

public boolean createNewAccount(String username, String password, 
                                String fullName, boolean role) 
    throws NamingException, SQLException {
    boolean result = false;
    Connection con = null;
    PreparedStatement stmt = null;
    int iCount = 0;
    
    try {
        con = DBHelpers.makeConnection();
        if (con != null) {
            
            String queryStr = "INSERT INTO "
                    + "accountInfo(username, password, lastname, isAdmin) "
                    + "VALUES(?, ?, ?, ?)";
            
            stmt = con.prepareStatement(queryStr);
            stmt.setString(1, username);
            stmt.setString(2, password);
            stmt.setNString(3, fullName);
            stmt.setBoolean(4, role);
            
            iCount = stmt.executeUpdate();
            
            if (iCount > 0) {
                result = true;
            }
        } // EndIf Connected
    } finally {
        if (stmt != null) {
            stmt.close();
        }
        if (con != null) {
            con.close();
        }
        return result;
    }
}

还有我的函数式 Servlet CreateNewAccountServlet.javaprocessRequest 方法:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    
    String username = request.getParameter("txtUsername");
    String password = request.getParameter("txtPassword");
    String confirm = request.getParameter("txtConfirm");
    String fullname = request.getParameter("txtFullname");
    
    String url = ERROR_PAGE;
    
    AccountInfoCreateError errors = new AccountInfoCreateError();
    boolean foundErr = false;
    
    try {
        // 1. Check valid user input
        if (username.trim().length() < 6 || username.trim().length() > 30) {
            foundErr = true;
            errors.setUsernameLengthErr("Username requires input from 6 to 30 characters!");
        }
        
        if (password.trim().length() < 6 || username.trim().length() > 20) {
            foundErr = true;
            errors.setPasswordLengthErr("Password requires input from 6 to 20 characters!");
        } else if (!password.trim().equals(confirm.trim())) {
            foundErr = true;
            errors.setConfirmNotMatch("Confirm mus be matched with password!");
        }
        
        if (fullname.trim().length() < 2 || fullname.trim().length() > 50) {
            foundErr = true;
            errors.setFullNameLengthErr("Full name requires input from 2 to 50 characters!");
        }
        
        if (foundErr) {
            request.setAttribute("CREATE_ERROR", errors);
        } else {
            // 2. Call DAO
            AccountInfoDAO dao = new AccountInfoDAO();
            boolean result = dao.createNewAccount(username, password, fullname, false);
            if (result) {
                url = LOGIN_PAGE;
            }
        }
        
    } catch (SQLException ex) {
        String errMsg = ex.getMessage();
        log("CreateNewAccountServlet SQL: " + errMsg);
        if (errMsg.contains("Duplicate")) {
            errors.setUsernameIsExisted(username + " is existed");
            request.setAttribute("CREATE_ERROR", errors);
        }
        
    } catch (NamingException ex) {
        log("CreateNewAccountServlet Naming: " + ex.getMessage());
    }
    finally {
        RequestDispatcher rd = request.getRequestDispatcher(url);
        rd.forward(request, response);
        out.close();
    }
}

当我运行我的应用程序时,一切正常。可以成功创建一个普通的新帐户并将其插入数据库。但是,当我尝试插入具有重复用户名的帐户(这是我在表中的主键)时,它不会抛出 SQLException,这是预计会发生的。当然,我的 TomCat 服务器不写日志。 我所有的朋友都这样做了,但抛出了异常。 我尝试重新安装我的 MS SQL Server,尝试使用不同的 JDBC 驱动程序,但结果是一样的。

我正在使用 JDK 8、NetBeans 8.2 RC、Apache Tomcat 8.0、MS SQL Server 2012 来实现这个应用程序。

希望你能帮我解决这个问题!

------- 更新 我在 MS SQL Server 中的表设计

【问题讨论】:

  • 向我们展示 DDL。断言你有一个主键,然后展示一些嵌入在 Java 中的 DML 并不能激发信心。 fullname vs lastnameisAdmin vs role(作为boolean 不少于)。我所看到的让我感到紧张。
  • @ElliottFrisch 嘿,我只是在我的问题中更新了我的表格设计,如果这就是你的意思的话。
  • 一个名为 username 的字段应该与一个唯一的约束一起使用。这不是java问题。尝试从 SQL 控制台插入双行,你也不会得到 SQLException
  • @DmitriiBykov 我在username 旁边的图形中看到了一个“钥匙”图标。我认为这意味着已经分配了主键约束,因此隐含了唯一约束?
  • 嘿@DmitriiBykov,我在 SQL Management Studio 中运行了一个 SQL 查询:“插入 accountInfo 值 ('trtranphong', '123456789', 'Phong', 0)”我收到一个错误:“违反PRIMARY KEY约束'PK_accountInfo'。无法在对象'dbo.accountInfo'中插入重复键。重复键值为(trtranphong)。语句已终止。”

标签: java web tomcat8 java-ee-7 sqlexception


【解决方案1】:

我已经找到了解决方案。我必须将return result; 行从finally 块中取出,我的应用程序运行良好!感谢您的帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-23
    • 1970-01-01
    • 2012-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    相关资源
    最近更新 更多