Sub-Classes, Shared IDs, and Hibernate
Finding common functionality and shoving it into a superclass can be extremely helpful in Java, particularly when you want a list of things that have that stuff in common and don’t particularly care (at the time) about the special properties those objects have. Heck, that’s what Object Oriented Programming is all about.
Hibernate does a good job of representing Object Relationships, understanding how they are to be mapped in the database, fetching them out of the database, and putting the properties into objects so that the programmer doesn’t have to worry too much about that.
One place Hibernate seems to fall down is this: If your ID information is contained in the superclass, Hibernate does not understand subclassing enough to grab from the correct table. I don’t know what the criteria are for which tables it looks in first, maybe the first one mapped, maybe the first one inserted into, but if you have an ID clash between two subclass tables, there is no guarantee that you will be getting the right data.
In general, Hibernate messages this correctly, letting you know that, hey, this is the wrong type. However, if you are using an association table for a many-to-one mapping, that goes a little beyond what Hibernate understands, I think, and the messaging is a little obscure:
org.hibernate.PropertyAccessException: could not set a field value by reflection setter [field-name]
My first reaction to this was to check and see if there was something wrong with either end of the association. Nope. They were both coded fine. Then to check the getters and setters in the association table. Nope. Fine. So, I went on google. They confirmed my “check your types and methods” vibe, which was very self-affirming, if completely useless.
Then I remembered that I’d gotten the wrong type errors with one end of the association, and had fixed that by monkeying with my IDs, making sure they were all unique, not just per table, but across all the tables that derived from the superclass. The same class structure exists for the association table (many subclasses deriving from one superclass with the ID information in the superclass) so I monkeyed with my association table IDs and, lo-and-behold, everything worked. It was fetching the association table and bringing the one end of the association along with it, just fine.
So, if there’s a moral to this story, which I’m not sure there is, but if there is, it’s “Be careful with your test data” or “Keep your metadata in one spot” or “Hibernate is useful but not all-knowing”. Sure, not a great moral, but if you’re having trouble tracking down a “org.hibernate.PropertyAccessException: could not set a field value by reflection setter” issue, this could be your ticket.
Leave a Comment