Derby caches prepared statements instances on a per-database basis in the statement cache, to avoid the overhead of re-preparing the statements.
The statement cache can be disabled by setting derby.language.statementCacheSize=0, though this parameter is not currently documented (DERBY-4280).
Some code to look at while studying the statement cache includes:
GenericStatement.equals and GenericStatement.hashCode
There are some problems involved in using the statement cache. For one thing, sometimes the statement cache causes us to fail to re-compile a statement when we *should* recompile it (for example, if we were to recompile it now, we'd get a better query plan) -- DERBY-3892.
For another thing, the statement cache may cause us to need to recompile the statement at an awkward time, leading to deadlocks -- DERBY-4279
The cached statements can be shared between many java.sql.Statement (or PreparedStatement or CallableStatement) instances. Since the validity of the compiled plan is checked frequently during execution, and the plan is possibly shared between multiple threads, the monitor that guards the isValid field in GenericPreparedStatement may become contended in multi-threaded scenarios and prevent multi-core scalability -- DERBY-3024.