days
-3
-9
hours
-2
-3
minutes
-2
-6
seconds
-1
-1
search
JAX Developers Puzzle deadline approaching: Play for a chance to win a complimentary JAX London 2018 ticket!
A new Type of movement

Don’t be Fooled by Generics and Backwards-Compatibility. Use Generic Generic Types!

Lukas Eder
French Bulldog image via Shutterstock

After having a sudden… burst of inspiration, Lukas Eder was ready to embark on a total rewrite. After some careful digestion, he isn’t feeling pooped at all about the new Generic Type of solution he’s come up with.

This post was originally published over at jooq.org, a blog focusing on all things open source, Java and software development from the perspective of jOOQ.

I’ve recently had a very interesting discussion with Sebastian Gruber from Ergon, a very early jOOQ customer, whom we’re in close touch with. Talking to Sebastian has lead our engineering team to the conclusion that we should completely rewrite the jOOQ API. Right now, we already have lots of generics for various purposes, e.g.

  • Generics for column types, such as
interface Field<T> { ... }
Field<String> field = BOOK.TITLE;
  • Generics for table types, such as
interface Table<R extends Record> { ... }
Table<BookRecord> books = BOOK;
  • Combined generics where both <T> and <R> are used
  • … and much more

Sometimes, you just cannot anticipate how many different generic types you’ll need on your classes and interfaces two years down the line, and the problem with Java is: You can generify your classes only exactly once. Let’s assume that you’ve always had a type like this:

class Foo {}

Now you happen to know that you need two generic type parameters right now:

// Still compatible
class Foo<Bar, Baz> {}

That’ll work and all the existing client code will still compile, with a rawtype warning. But once you’ve published Foo<Bar, Baz>, you can no longer add more type variables to it, or remove them. Every modification will break client code!

// Breaking change
class Foo<Bar, Baz, Fizz> {}

The solution: Generic generic types

We don’t want to place that burden upon our customers, the heavy burden of backwards-incompatibility. This is why we’re now publishing our next release of jOOQ with a new feature that we call generic generic types. How does it work? It’s easy. We’ve learned from the best database designers who have already been using generic column types all along. In SQL, if you run into this kind of problem, you’d simply write:

CREATE TABLE foo (
    bar int,
    baz int,
    fizz int,

    generic_1 varchar(4000),
    generic_2 varchar(4000),
    generic_3 varchar(4000),
    generic_4 varchar(4000),
    -- [...]
);

Now your SQL schema is safe for ages to come. We’ll do the same in Java:

class Foo<
    Bar,
    Baz,
    Fizz,

    Generic1,
    Generic2,
    Generic3,
    Generic4,
    // [...]
> {}

We’ll thus generify all our types to have exactly 256 generic type parameters. 256 was the sensible limit that MS Access chose for the number of possible columns. That way, our customers will only have to upgrade to the new version of jOOQ once and from then on, generic type backwards-compatibility will be guaranteed forever.

Happy coding!

Author
Lukas Eder
Lukas is a Java and SQL aficionado. He’s the founder and head of R&D at Data Geekery GmbH, the company behind jOOQ, the best way to write SQL in Java.

Leave a Reply

Be the First to Comment!

avatar
400
  Subscribe  
Notify of