【问题标题】:Java SQL null object throws MySQLIntegrityConstraintViolationException and not customized exceptionJava SQL null 对象抛出 MySQLIntegrityConstraintViolationException 而不是自定义异常
【发布时间】:2016-02-24 05:35:51
【问题描述】:

使用 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));
        }
    }
}

还有以下类来扩展Exception:

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)

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

有办法解决吗?

非常感谢!

【问题讨论】:

  • 我们还需要TaskBusinessLogic.addTaskSimpleTest.runTest 方法的代码,它们显示在堆栈跟踪中。
  • 我已经添加了方法。谢谢!

标签: java mysql exception


【解决方案1】:

答案很简单: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 ...
    }

【讨论】:

  • 就是这个原因!非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-05
  • 1970-01-01
  • 1970-01-01
  • 2012-09-18
  • 2018-07-09
  • 1970-01-01
相关资源
最近更新 更多