Compression function in Postgres
I've recently had the occasion to use something like this:

CREATE FUNCTION gzip(text) RETURNS bytea
    LANGUAGE plperlu IMMUTABLE STRICT COST 100000 PARALLEL SAFE
    AS $_X$
    use Compress::Zlib;
    my $x = Compress::Zlib::memGzip($_[0]);
    return encode_bytea($x);
$_X$;


But note that bytea is itself transmitted in an escaped form which will enlarge the size.  With any luck, JDBC implementation might unescape them on the fly as they are read into memory, and not store the entire result set in the raw form.  Sorry, I don't use JDBC enough to know.

Can't you just use a cursor to process one row at a time and then discard it, rather than reading all rows into memory?