Here is the code of a class which I am writing which uses JooQ 3.7.0 (the irrelevant parts have been stripped); note the uses of the AutoCloseable
feature of DSLContext
:
public final class JooqPerMethodMetricWriter
implements PerMethodMetricWriter
{
private static final Logger LOGGER
= LoggerFactory.getLogger(JooqPerMethodMetricWriter.class);
// [snip]
private final DSLContext jooq;
public JooqPerMethodMetricWriter(final Connection connection,
final Instant instant)
throws IOException
{
// [snip]
jooq = DSL.using(connection);
}
private void writeCsv(final Configuration configuration)
{
// [snip]
try (
final DSLContext context = DSL.using(configuration);
final Reader reader = Files.newBufferedReader(csvPath);
) {
final Loader<PermethodMetricsRecord> loader = context
.loadInto(PERMETHOD_METRICS)
.loadCSV(reader)
.fields(PERMETHOD_METRICS.fields())
.execute();
LOGGER.info("{} lines stored in database", loader.stored());
} catch (IOException e) {
throw new RuntimeException("Cannot open CSV for reading", e);
}
// BREAKPOINT 1
}
@Override
public void close()
throws IOException
{
jooq.transaction(this::writeCsv);
jooq.close();
// BREAKPOINT 2
Files.delete(csvPath);
}
// [snip]
}
If relevant at all, the database used is PostgreSQL (9.4.x).
In the code above, I have two breakpoints. When I debug, I see that:
configuration.connectionProvider().acquire().isClosed()
is false...jooq.configuration().connectionProvider().acquire().isClosed()
is also false.I'm confused. What happened to the Connection
which I have received as a constructor parameter? Do I need to .close()
it myself?
Side question, this time with regards to the Loader
: I leave the defaults, therefore .commitNone()
; given that I run the loader within a transacation, would it make a difference at all if I tried and .commit<somethingElse>()
instead, for instance .commitAfter(1000)
?
This question became outdated with the introduction of the CloseableDSLContext
, when the AutoCloseable
semantics was removed again from the more general-purpose DSLContext
. The incompatible change was implemented in jOOQ 3.14, in order to address the confusion expressed in this question and a few others, see:
https://github.com/jOOQ/jOOQ/issues/10512
DSLContext
became AutoCloseable
with the Java 8 distributions of jOOQ 3.7. The DSLContext.close()
method's Javadoc explains the semantics of this close()
call:
Close the underlying resources, if any resources have been allocated when constructing this
DSLContext
.Some
DSLContext
constructors, such asDSL.using(String)
,DSL.using(String, Properties)
, orDSL.using(String, String, String)
allocate aConnection
resource, which is inaccessible to the outside of theDSLContext
implementation. Proper resource management must thus be done via thisclose()
method.
Only resources allocated when you constructed the DSLContext
will be released. Not resources that you passed to the DSLContext
. In your case, you are not allocating any resources in this try-with-resources
statement, so there is nothing to be released at the end of it:
try (DSLContext context = DSL.using(configuration); ...) { ... }
This would be different if you allocated a new Connection
right there:
try (DSLContext context = DSL.using("jdbc:h2:~/test", "sa", ""); ...) { ... }
I'm confused. What happened to the Connection which I have received as a constructor parameter?
Nothing. You must govern its lifecycle yourself as jOOQ doesn't know anything about your connection lifecycle strategy.
Do I need to .close() it myself?
Yes.