Hibernate chokes on missing rows when dealing with a legacy database
Asked Answered
S

4

14

I am trying to implement hibernate on a legacy database (that still has a legacy PHP client), and am running into some problems because the people who wrote the original app had no idea what they were doing.

The database is set up so that none of the columns are nullable, so they default foreign keys to 0 if there is no record for them. Additionally, they don't have proper foreign keys on the tables so there are a few with invalid IDs. I do not have an option to change the schema or null the appropriate columns.

This is the error I get from hibernate:

Caused by: org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.tv.platform.domain.Program#0]

What I would like is a graceful way to deal with this muck, where the field will just null if the row is invalid or doesn't exist, but I am not having any luck finding how to handle this in the documenation.

Any tips?

Siliqua answered 26/4, 2011 at 18:58 Comment(0)
S
16

The annotation: @NotFound( action = NotFoundAction.IGNORE )

Does exactly what I was looking for. I found it through here:

Hibernate Many-To-One Foreign Key Default 0

Siliqua answered 26/4, 2011 at 21:21 Comment(1)
Starting point for what I was looking for. For Hibernate mapping files, the attribute is not-found1 (ex: <many-to-one ... not-found="ignore" />)Sou
S
2

I don't think Hibernate is a good fit for this type of problem. Hibernate expects the records in your tables to relate to each other, and really can't work if the foreign-key relationships are only sometimes enforced. I can't imagine it would be easy to change or configure Hibernate to behave this way - to know how to deal with broken foreign-key relationships.

You may get more mileage out of a framework like MyBatis SQLMaps, in which you provide the SQL statements to load your data in files external to your program, but the framework provides options for chaining SELECT statements together to load full object graphs. This way you could supplement the SQL statements with logic to filter out the 0 values.

Sidewinder answered 26/4, 2011 at 19:19 Comment(1)
Thanks for the suggestion, but I'm stuck with hibernate. I have found decent workarounds so far, but it would be nice if I could trap that particular exception and just null the field.Siliqua
R
1

I think an interceptor might do the trick.

Rozele answered 26/4, 2011 at 19:52 Comment(1)
I checked out interceptors, and outside of several examples of using them to create audit logs, it seemed to be a little bit too general. The annotation I listed elsewhere ended up doing what I wanted.Siliqua
H
0

I recently programmed a webapp against a legacy database with similar issues. You can still use hibernate, if you don't want to use multiple data access frameworks. What I did is write out native SQL queries for the tricky parts using 'createSqlQuery'. In some cases I had to map complete subqueries or computed values to an entity property, but it works. For parts of the database that were more regular I could still use regular Hibernate mappings and criteria/HQL queries.

Another thing: maybe you should refrain from using terms like 'no idea what they were doing' or 'muck' a bit. I know it is tempting to view any code left to you by predecessors as inferior, but realize that these people probably did the best they could at the time. Also, your own code is not flawless either, so some humility is in place. Why? For one, people around you might get along with you a bit better if you are not foaming around the mouth all the time about the previous developer(s) who they thought were very knowledgeable. Just a tip.

Hobnob answered 26/4, 2011 at 19:54 Comment(1)
How can you be sure I haven't? Maybe I wrote it.Hobnob

© 2022 - 2024 — McMap. All rights reserved.