A generic JDBC prepare Action Framework (2)

Source: Internet
Author: User
Exception Handling

Exception Handling

Exception Handling is such an important issue that we shoshould develop a consistent strategy for it before we begin to implement our framework proper.

Exception Handling is so important that when we begin to implement our own framework features, we must develop a persistent strategy for it.

The jdbc api is an object lesson in howNotTo use exceptions. as well as ensuring that we release resources even if we encounter errors, our login action layer shoshould provide a better Exception Handling Model for application code than JDBC does.

Jdbc api is an object lesson in error handling. Make sure that we release resources even if we encounter an error. Comparison of JDBCCodeThe abstract layer of the application code must provide a better exception handling model.

JDBC uses a single exception class-Java. Lang. sqlexception-For all problems before t data truncation. CatchingSqlexceptionIn itself provides no more information than "something wrong". As we 've seen, it's only possible to distinguish between problems by examining potentially vendor-specific codes included in SQL exceptions.

JDBC uses a single exception class --- java. Lang. sqxexception -- except for data Truncation for all problems. Self-capturing a sqlexception provides some errors and no more information. As we can see, it may only differentiate the problem by checking the potential vendor-detailed code is included in SQL exception.

JDBC cocould in fact have offered more sophisticated error handling while retaining portability between databases. The following are just a few of the errors that are meaningful in any RDBMS:

JDBC can in fact provide more precise error processing when the portability between databases is retained. The following errors make sense in any RDBMS:

    • Grammatical error in SQL statement issued using JDBC

    • Syntax errors when SQL statements are released and used

    • Data Integrity Constraint Violation

    • Violation of data integrity constraints

    • Attempt to set the value of a SQL Bind Variable to an incorrect type

    • Try to bind the SQL value variable to an incorrect type

Such standard problems cocould-And showould-have been modeled as individual subclassesJava. Lang. sqlexception. In our your action framework, we will provide a richer exception hierarchy that does use individual exception classes.

This standard problem may be-it should be-it has been modeled as a subclass of Java. Lang. sqlexception. In our abstract framework, we will provide a rich exception level, compared to using this single exception subclass.

We'll also address two other issues with JDBC exception handling.

We will also use JDBC exception handling to emphasize two other problems.

  • We don't want to tie code using our login action layer to JDBC. our your action layer is primarily intended for use to implement the data-Access Object pattern. if code using daos ever needs to catch resource-specific exceptions, suchSqlexceptions, The decoupling of business logic and data access implementation that the DAO pattern exists to provide is lost. (Exceptions thrown are an integral part of method signatures .) so while the jdbc api, reasonably enough, uses JDBC-specific exceptions, we won't tie our exceptions to JDBC.

  • We do not want to use our abstraction layer to associate JDBC code. The main purpose of our abstraction layer is to use it to implement the Data Access Object Mode. If the Code uses Dao to capture exceptions of specific resources, such as sqlexception, the decoupling of business logic and data access implementation will not work in DAO mode. (Exception throws are part of the method declaration ). Therefore, when the jdbc api is reasonable enough to use the exception specified by JDBC, We will depend on the exception of JDBC.

  • Following our discussion of checked and runtime exceptions in chapter 4, we will make our API much easier to use by making all exceptions runtime, rather than checked exceptions. JDO takes this approach with good results. using runtime exceptions, callers need catch only those exceptions (if any) that they may be able to recover from. this models JDBC (and other data-Access) usage well: JDBC exceptions are often unrecoverable. for example, if a SQL query contained an invalid column name, there's no point catching it and retrying. we want the fatal error logged, but need to correct the offending application code.

  • In Chapter 4th, we will discuss how to check and run exceptions. We will make it easier for our APIs to use them by making all the exception programs run, compared to checking exceptions. JDO uses this method to obtain the result with a nickname. When running exceptions are used, the caller needs to capture only these exceptions (if any) and they may recover from them. JDBC model (and other data access) usage Convention: JDBC exceptions are often irrecoverable. For example, if an SQL production line contains an invalid column name, it is meaningless to capture it and try again. We want a fatal error log, but do not need to change it to the provided application code.

  • If we're re running the query from an EJB, we can simply let the EJB container catch the runtime exception and roll back the current transaction. if we caught a checked exception in the EJB implementation we 'd need to roll back the transaction ourselves, or throw a runtime exception that wowould cause the container to do so. in this example, using a checked exception wocould allow more scope for application code to cause incorrect behavior. likewise, failure to connect to a database is probably fatal. in contrast, a recoverable error that we might want to catch wocould be an Optimistic Locking violation.

  • If we run the query from EJB, we can simplify the process of letting the EJB container capture runtime exceptions and roll back the current transaction. If we capture a check exception in rjb implementation, we need to roll back the transaction ourselves, or throw a runtime exception that will cause the container to do something. In this example, an exception check will allow more code in the application scope to cause incorrect behavior. Similarly, failed connection to a database may be fatal. On the contrary, what we want to capture for a recoverable error is a violation of the optimistic lock.

A generic data-access exception hierarchy

A common data access level

We can meet all our Exception Handling goals by creating a generic data-access exception hierarchy. this won't be limited to use with JDBC, although some JDBC-specific exceptions will be derived from generic exceptions within it. this exception hierarchy will enable code using daos to handle exceptions in a database-agnostic way.

We can meet all our Exception Handling objectives and create a common data exception level. This will not limit the use of jbdc, even if some specific JDBC exception sources and general exceptions. This exception level may be because the Code uses the DAO mode to handle exceptions in a way that does not rely on the database.

The root of all data-access exceptions is the abstractDataaccessexceptionClass, which extendsNestedruntimeexceptionClass discussed in Chapter 4. UsingNestedruntimeexceptionSuperclass enables us to preserve the stack trace of any exceptions (suchSqlexceptions) We may need to wrap.

The root cause of all data access exceptions is abstraction.The dataaccessexception class inheritsNestedruntimeexceptionClass. UseNestedruntimeexceptionThe parent class allows us to retain any stack trace of exceptions (such as sqlexception) that we need to wrap.

UnlikeSqlexception,DataaccessexceptionHas several subclasses that indicate specific data-access problems. The direct subclasses are:

Unlike sqlexception,Dataaccessexception has several subclasses that imply specific data access problems. The direct subclass is:

  • Dataaccessresourcefailureexception
    Complete failure to access the resource in question. In JDBC implementation, this wowould result from failure to get a connection from a datasource. However, such errors are meaningful for any persistence strategy.

  • Access to resources with complete failures is under discussion. In JDBC implementation, this will cause connection failure. However, these errors are meaningful to any persistent strategy.

  • Cleanupfailuredataaccessexception
    Failure to clean up (for example, by closing a JDBCConnection) After successfully completing an operation. in some cases we might want to treat this as a recoverable error, preventing the current transaction from being rolled back (for example, we know that any update succeeded ).

  • Failed to clear (for example, close the JDBC connection) after a successful operation is completed. In some cases, we may want to treat this as an irreparable error to prevent the current transaction from being rolled back (for example, we know any successful updates ).

  • Dataintegrityviolationexception
    Thrown when an attempted update is rejected by the database because it wowould have violated data integrity.

  • Throw an exception that is rejected by the database because it violates the integrity of the database.

  • Invaliddataaccessapiusageexception
    This exception indicates not a problem from the underlying resource (such asSqlexception), But incorrect usage of the data-access API. The JDBC wait action layer discussed below throws this exception when it is used incorrectly.

  • Exceptions indicate that the underlying resources are not a problem (for example, sqlexception), but incorrect data access API usage. The JDBC abstraction layer is discussed below when it is incorrectly used and throws an exception.

  • Invaliddataaccessresourceusageexception
    This exception indicates that the data-access resource (such as an RDBMS) was used incorrectly. for example, our JDBC login action layer will throw a subclass of this exception on an attempt to execute invalid SQL.

  • Data access resources are incorrectly used.

  • Optimisticlockingviolationexception
    This indicates an Optimistic Locking violation and is thrown when a competing update is detected. This exception will normally be thrown by a data-access object, rather than underlying API like JDBC.

  • Violation of the optimistic lock.

  • Deadlockloserdataaccessexception
    Indicates that the current operation was a deadlock loser, causing it to be rejected by the database.

  • The current operation is a deadlock, causing it to be rejected by the database.

  • Uncategorizeddataaccessexception
    An exception that doesn' t fit within the recognized categories listed above. this exception is abstract, so resource-specific exceptions will extend it carrying additional information. our JDBC login action layer will throw this exception when it catchesSqlexceptionIt cannot classify.

  • An exception is not suitable for the category listed above.

All these concepts are meaningful for any persistence strategy, not just JDBC. Generic exceptions will include nested root causes, suchSqlexceptions, Ensuring that no information is lost and ensuring that all available information can be logged.

All of these concepts make sense for persistence policies, not just JDBC. General exceptions include internal and exceptions, such as sqlexception, so that no more information is lost and all variable information can be recorded.

The following UML class dimo-strates our exception hierarchy, contained inCom. interface21.daoPackage. note how some JDBC-specific exceptions inCom. interface21.jdbc. CorePackage (shown below the horizontal line) Extend generic exceptions, enabling the maximum information to be encoded about a problem without making calling code dependent on JDBC. calling code will normally catch generic exceptions, although JDBC-specific Dao implementations can catch JDBC-specific subclasses they understand, while lew.fatal errors propagate to business objects that use them.

The following UML class diagram shows our exception layers, includingCom. interface21.daoPackage. Note that some JDBC exceptions occur inCom. interface21.jdbc. Core Package (displayed in the following horizontal line ).

Although this exception hierarchy may appear complex, it can help to deliver a great simplification in application code. all these exception classes will be thrown by our framework; application code need only catch those it considers recoverable. most application code won't catch any of these exceptions.

Even if the exception hierarchy may be complex, it can help provide a great way to simplify the application code. All of these exception classes will be thrown by our framework; the application code only needs to capture these classes that are considered recoverable. Most application code cannot catch these exceptions.

This hierarchy automatically gives us much more useful information thanSqlexceptionAnd makes application code that needs to work with exceptions much more readable. While we can choose to catch the baseDataaccessexceptionIf we want to know ifAnythingWent Wrong (in the same way as we catchSqlexception), It will be more useful in most cases to catch only a participant subclass.

These exceptions automatically give us more useful information than sqlexception, and the application code needs to work more readable with exceptions. When we select graph captureDataaccessexceptionIf we want to know whether an error occurs (we capture a sqlexception in the same way), it will be used to capture only one specific subclass in most cases.

Consider a plausible requirement to perform an update operation and apply a recovery strategy if the operation resulted in a data integrity violation. in an RDBMS context, the operation might have attempted to set a non-nullable column's value to null. using the exception hierarchy we 've just examined, all we need to do is catchCom. interface21.dao. dataintegrityviolationexception. All other exceptions can be ignored, as they're unchecked. The following code clearly conveys the recovery ment just described. As a bonus, it isn' t dependent on JDBC:

Consider a reasonable request to perform an update operation. Apply a recovery policy. If the operation results in a data constraint error. In an RDBMS context, the operation may try to set the value of a non-empty column to null. With the exception levels we checked, all we need to do is captureCom. interface21.dao. dataintegrityviolationexception. All other exceptions can be ignored because they are not checked. The following code clearly conveys the requirements just described. As a reward, he does not rely on JDBC:

Try{
// Do data operation using JDBC prepare action Layer
}
Catch(Dataintegrityviolationexception ex ){
// Apply recovery strategy
}

Now consider how we wowould need to do this using JDBC, without an arbitrary action layer.SqlexceptionsAre checked, we can't let exceptions we're not interested in through. The only way to establish whether weAreInterested in the exception is to examine itsSqlstateString or vendor code. In the following example we checkSqlstateString. As this may beNull, We need to check it's non-null before examining it:

Now let's consider how to use JDBC without an abstraction layer. Sqlexception is checked. We cannot pass exceptions that we are not interested in. The only exception is to check whether the resume is an SQL status string or vendor code. In the following example, we can check the sqlstate string. This may be null. We need to check the non-null:

 Try {
// Do data operation using JDBC
}
Catch (Sqlexception ex )(
Boolean Recovered = false;
String sqlstate = sqlex. getsqlstat ();
If (Sqlstate! = NULL ){
String classcode = sqlstate. substring (0, 2 );
If ( "23" . Equals (classcode) |
"27" . Equals (classcode) |
"44" . Equals (classcode )){
// Apply recovery strategy
Recovered = true;
}
}
If (! Recovered)
Throw New Applicationspecificexception ( "Other SQL exception" , Ex );
}
// Finally block omitted

There's no doubt which is the simpler, more readable, and more maintainable approach. not only is the second approach far more complex, it makes the calling code dependent on intimate details of the jdbc api.

There is no doubt that this is a simple, readable, and maintainable approach. More complicated than just 2nd channels, it makes calling code dependencies and jdbcapi.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.