JPA / Hibernate and things I’ve learnt about the OrderColumn annotation

I’ve just spent the last two or three hours wondering why REST requests to my application have all been failing. The application in question is SpringBoot based (version 2.3.3, but I doubt that matters much) and is pretty simple with just a few domain objects. The error has been reporting itself as a “500 Internal Server Error” with no stack trace in the logs.

After much much head-scratching I decided to trace the request down into the guts of SpringBoot where I eventually got to the method ServletInvocableHandlerMethod.invokeAndHandle. In there I found a catch block which was catching and re-throwing and exception from the JSON serializer. The key part of the exception message was:

null index column for collection

This was key because it led me back to my domain object (lets pretend it was a Book) where I had an ordered list of child objects (Pages) in a one to many relationship. Like this:

@OneToMany ( cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinColumn(name = "pages_id")
@OrderColumn( name = "page_order")
private List<Page> pages = new ArrayList<>();

I was inserting some testing data into the database manually and, guess what, I’d forgotten to set the “page_order” column so it was null. For some reason Spring swallowed the exception for this which is decidedly unhelpful in my book.

The next problem was with null’s appearing in my page list, particularly at the start of the list. That was also my fault. In my test data I started numbering the pages at 1 when JPA was expecting a zero index (I’ll hand my coder card in at the door). That’s an interesting problem though as I don’t want any blank pages in the ordered list. I’ll have to do some testing to see how JPA handles that.

With the index starting at zero and being specified a whole host of problems have now vanished. What I don’t understand now though is why the pages list is being populated even though it’s set to lazy load.