simonpena.com Una mezcla heterogénea de tecnología y desvaríos

27Feb/091

Hibernate common errors

Just two days after I blogged about the errors deleted entity passed to persist, detached entity passed to persist and id to load is required for loading, some people came here from web searches.

As I'm not sure if those explanations were clear enough, I'll try to synthesise here:

  • Deleted entity passed to persist. One entity, supposed to be deleted, is still referenced / accessed. In my case, I had a problem with "cascading". The behavior I expected was "on delete cascade" and "on update cascade". I have those constraints well in the database, but they weren't right in the Hibernate annotations. After I changed that, the error stopped. While I was searching why I was getting this error, I've seen people whose problem was different. They had, let's say, a list of entities. Those entities were related to others, and, when deleting, they had to take care of deleting both the link and the persisted entity. This was the most common scenario of this problem, and is better explained here, for example.
  • Detached entity passed to persist. One entity, which is supposed to be up to date but is not, is passed to persist. In my case, I was trying to create an entity (an Operation), related to another (the Account where that Operation was taking place). The persist action was failing because my version of the Account was incorrect. The solution was just to update the entity.
  • Id to load is required for loading. Trying to access an entity without giving an actual identifier. In my case this was the easiest problem: I was calling find passing a non initialized long. Passing the correct, initialized values fixed the problem.
24Feb/090

Mind the Cascade

Today I decided to go through the model layer, implementing as many JUnit tests as I could, and completing all the actions I hadn't implemented yet. As I said before, I had just decided to stick to one-category-at-a-time scheme, having a hierarchical relationship between categories.

I thought it would be easy: change the Category entity, check the on delete and on update constraints in the database creation script, refactor and go on.I also had in mind some refactor in my JUnit tests: I have just two cases, one for each Facade, and several methods inside, for each of the actions in that facade. But as the application was getting larger and larger, I decided to have one JUnit case for each Facade Method, with several test methods for each of the possible scenarios I can think of.

So I was there, refactoring tests, moving some code to the setUpBeforeClass and tearDownAfterClass methods, when everything started to break:

deleted entity passed to persist and detached entity passed to persist. After some research in Google, I understood what could be causing the second error, so I solved it:

I was using an entity in a call to persist which had been "left" unchecked by the entity manager (detached is the word, but I didn't know it). I got the entity again by invoking find, and passed it fresh, and it worked out.

But the first problem was harder. Google didn't shed any light on me (apparently), as everything was about deleted entities which were still referenced by others related to them. I didn't have any entity left: this was happening in the tearDownAfterClass method, and I was removing the entities left after the test. And then I realized that most of the clean up was supposed to be done by cascading. So, maybe cascading tags were incorrect. I checked out my classes, and I changed some of them: putting the explicit ones instead of CascadeType.ALL. I still have to test some of the Update methods, but for today, it's fixed.