Java SQL 空对象抛出 MySQLIntegrityConstraintViolationException 而不是自定义异常

标签 java mysql exception

使用 java.sql。

使用以下类对数据库对象执行操作:

public class TaskBusinessLogic 
{
    private TaskDao taskDao = null;

    public TaskBusinessLogic(){
        taskDao = new TaskDaoImpl();
    }

    /**
     * Updates data in the table 'tasks' in the database
     * @param task Record in the table 'tasks' in the database to be updated
     * @throws ValidationException
     */
    public void updateTask(Task task) throws ValidationException
    {
        cleanTask(task);
        validateTask(task);
        taskDao.updateTask(task);
    }

    private void cleanTask(Task task)
    {
        if(task.getTitle() != null)
        { 
            task.setTitle(task.getTitle().trim());
        }
        if(task.getPriority() != null)
        { 
            task.setPriority(task.getPriority().trim());
        }
        if(task.getNote() != null)
        { 
            task.setNote(task.getNote().trim());
        }
    }

    private void validateTask(Task task) throws ValidationException
    {
        validateString(task.getTitle(), "Title", TITLE_MAX_LENGTH, true);
        validateString(task.getPriority(), "Priority", PRIORITY_MAX_LENGTH, true);
        validateString(task.getNote(), "Note", NOTE_MAX_LENGTH, true);
        validateDate(task.getDateCompleted());
        validatePriority(task.getPriority());
    }

    private void validateString(String value, String fieldName, int maxLength, boolean isNullAllowed) 
            throws ValidationException
    {
        if(value == null && isNullAllowed)
        {
            // return; // null permitted, nothing to validate
        }
        else if(!isNullAllowed && value == null)
        {
            throw new ValidationException(String.format("%s cannot be null", fieldName));
        }
        else if(value.length() == 0)
        {
            throw new ValidationException(String.format("%s cannot be empty", fieldName));
        }
        else if(value.length() > maxLength)
        {
            throw new ValidationException(String.format("%s cannot exceed %d characters", 
                    fieldName, maxLength));
        }
    }
}

和下面的类来扩展异常:

public class ValidationException extends Exception
{
    public ValidationException()
    {
        super("Data not in valid format");
    }

    public ValidationException(String message)
    {
        super(message);
    }


    public ValidationException(String message, Throwable throwable)
    {
        super(message, throwable);
    }

    public ValidationException(Throwable throwable)
    {
        super(throwable);
    }
}

编辑:这是 updateTask 方法:

public void updateTask(Task task)
    {
        Connection connection = null;
        PreparedStatement pStatement = null;
        try{
            DataSource ds = new DataSource();
            connection = ds.createConnection();
            pStatement = connection.prepareStatement("UPDATE tasks SET Title = ?, Priority = ?, IsComplete = ?, "DateCompleted = ?, Note = ? WHERE TaskID = ?");
            pStatement.setString(1, task.getTitle());
            pStatement.setString(2, task.getPriority());
            pStatement.setBoolean(3, task.getIsComplete()); 
            pStatement.setDate(4, task.getDateCompleted());
            pStatement.setString(5, task.getNote());
            pStatement.setInt(6, task.getTaskId().intValue());
            pStatement.executeUpdate();
        }
        catch(SQLException e)
        {
            e.printStackTrace();
        }
        finally
        {
            try{ if(pStatement != null){ pStatement.close(); }}
            catch(SQLException ex){System.out.println(ex.getMessage());}
            try{ if(connection != null){ connection.close(); }}
            catch(SQLException ex){System.out.println(ex.getMessage());}
        }
    }

并运行测试:

public void runTest()
    {
        try
        {
            TaskBusinessLogic logic = new TaskBusinessLogic();
            List<Task> list = null;
            Task task = null;            

            // testing validation
            try
            {
                System.out.println("Checking for exception from null title.");
                task = new Task();
                task.setTaskId(taskId);
                task.setPriority("high");
                logic.updateTask(task);
                System.out.println("well that didn't work");
            }
            catch(ValidationException e)
            {
                System.out.println("Title null check: " + e.getMessage());
            }
            System.out.println();
         }
         catch(ValidationException e){
             System.err.println(e.getMessage());
         }
}

因此,当我尝试检查异常并创建具有空标题和优先级的记录时,它不会抛出用户友好的异常,而是抛出:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'Title' cannot be null
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
    at com.mysql.jdbc.Util.getInstance(Util.java:387)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:934)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3870)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3806)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2470)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2617)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2550)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
    at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073)
    at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009)
    at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5094)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994)
    at dataaccesslayer.TaskDaoImpl.addTask(TaskDaoImpl.java:235)
    at businesslayer.TaskBusinessLogic.addTask(TaskBusinessLogic.java:74)
    at SimpleTest.runTest(SimpleTest.java:86)
    at Launcher.main(Launcher.java:21)

而其他错误是通过控制台中的友好通知捕获的。

有办法解决吗?

非常感谢!

最佳答案

答案很简单:validateTask 方法什么都不做,因为您在验证 TITLE 属性时明确允许空值:

validateString(task.getTitle(), "Title", TITLE_MAX_LENGTH, true);

true 应该是 false

无论如何,我建议您重构 validateString 方法,使其更清晰易读:

    private void validateString(String value, String fieldName, int maxLength, boolean isNullAllowed)
        throws ValidationException
    {
        if (value == null)
        {
            if (isNullAllowed)
            {
                // return; // null permitted, nothing to validate
            }
            else
            {
                throw new ValidationException(String.format("%s cannot be null", fieldName));
            }
        }
        else ...
    }

关于Java SQL 空对象抛出 MySQLIntegrityConstraintViolationException 而不是自定义异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33848577/

相关文章:

java - 在方法中访问spring注解属性

Mysql触发器在特定列更新时将记录插入到另一个表中

c# - InvalidProgramException/Common Language Runtime 检测到无效程序

database - 如何检查值是否在数据库中而不在 Zend 中抛出异常?

java - SMTP - 通过代理发送电子邮件失败 (JAVA)

java - 假客户端单元测试

java - 如何在java中读取只有值的配置文件?

mysql - 从以下查询中选择每个结果之一

javascript - AngularJs中如何实现数据库变化后 View 自动更新?

windows - Win32 EXCEPTION_INT_OVERFLOW 与 EXCEPTION_INT_DIVIDE_BY_ZERO