Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Persisting an object that contains a non-saved class

 
dave taubler
Ranch Hand
Posts: 132
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I ran into an interesting problem with JUnit testing a Hibernate app I'm working on. Basically, I have a class, Movie, that contains as members a few other class instances (for example, it contains an instance of a Person class called "director").

Below is part of a test method for inserting the movie:


Now at this point, the test fails:

org.hibernate.PropertyValueException: not-null property references a null or transient value: com.package.Movie.director

So it seems that my director Person has a null ID, because it hasn't been saved yet, and that's causing problems with my composite Movie class. Granted, it's just a JUnit test, but I figure it could appear in a real-world scenario. So, what's the best way to deal with this scenario. Should I persist the director Person first? Or is there an auto-generating ID strategy that would work better in this scenario?

Thanks in advance.
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Basically you need to set a cascade option in your mapping of the relationship between the Movie and the Director. The cascade option will tell Hibernate that you want to Hibernate to make sure the child is inserted before the parent. Or it could be that you have a bi-directional mapping without putting in 'inverse="true"'

Mark
 
dave taubler
Ranch Hand
Posts: 132
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mark, thanks! I added to my mapping to director from Movie, and that works great.

I found another interesting issue, with a similar many-to-many mapping. In this case, Movie contains a Set of Person objects that I call "actors"; thus, there is a many-to-many relationship between Movie and Person there. If I've set some actors within a Movie, that relationship is reflected in a linking table in the database. If I then try to delete the Movie, I get a foreign key constraint violation; it makes sense, because in the linking table, the ID to my Movie still exists.

After researching this a bit, my thought is that I should simply remove all actors from my Movie (thus removing my Movie's ID from the linking table) and then delete the Movie. I'm guessing that would work fine. But it seems like such a commonplace scenario that I'm describing, that Hibernate would have a mechanism to handle this automatically. Is there anything I'm missing, or should I just clear out all actors before deleting a Movie?
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


Funny actually, it is another cascade option. There is "delete" and "delete-orphan" you probably will want "delete" but that is a guess. So when you map multiple cascade options, use a comma between them like

"save-update, delete"

or you can use "all", but All does not include "delete-orphan" if you need it.

Mark
 
dave taubler
Ranch Hand
Posts: 132
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah, ya know, I was thinking of that as a possible solution but dismissed it, because it seems that it would not only merely break the relationship between the Movie and the actor/Person (i.e. remove the row from the linking table), but also delete the Person in question. In my case, the latter is definitely not what I want to happen (I should've mentioned that). Still, I'll try it out anyway to test my assumption.

Either way, thanks again for the replies.
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by dave taubler:
Ah, ya know, I was thinking of that as a possible solution but dismissed it, because it seems that it would not only merely break the relationship between the Movie and the actor/Person (i.e. remove the row from the linking table), but also delete the Person in question. In my case, the latter is definitely not what I want to happen (I should've mentioned that). Still, I'll try it out anyway to test my assumption.

Either way, thanks again for the replies.


Yes, there is a difference between delete and delete-orphan. In "delete" it clears out the FK, setting it to Null, in your many to many, it should just delete a row from your link table. If you used "delete-orphan" then it would also delete the row from the Person table. So you want "delete"

Mark
 
dave taubler
Ranch Hand
Posts: 132
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the reply. I did try the 'delete' cascade approach, and it caused the deletion of the Persons attached to my Movie as actors when that Movie was then deleted (e.g. I had a Person, "Harrison Ford", in my database. I then created a Movie, "Raiders of the Lost Ark", and added the "Harrison Ford" Person as an actor, and then persisted the Movie. Then, I deleted the "Raiders of the Lost Ark" Movie. After that, "Harrison Ford" was no longer in the Person table.)

It could still be something I'm doing wrong, so I'll play around a bit, and if I find anything interesting I'll post it here, so that someone else might learn from my experiments. At any rate, thanks again; you've provided me with different approaches to play around and experiment with.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic