-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Cascading delete
PostPosted: Wed Aug 26, 2009 5:32 pm 
Beginner
Beginner

Joined: Fri Mar 21, 2008 8:07 pm
Posts: 23
Can someone help with a cascading delete problem? Code is below.

I have a Team that contains a set of Games. A Game refers to a home and an away team. If i delete a Team, I want all its games to be deleted. This means it should remove the games from the other Team's list of games too.

Right now, when i delete a team, all of its games are left in the DB. And then I get errors when I load lists of games since the home/away field refers to a team that doesn't exist anymore.

Is there something else I need to configure in my cascade besides CascadeType.ALL? Would delete-orphan even work, since the Game is still referred to by another Team?

Thanks,
Tauren

Code:
/*
// This code deletes the Team entity, but not the set of Games in the Team
Team team = getSession().load(Team.class, 5);
getSession().delete(team);

// How do I make it cascade to delete the Games as well?  Note that a Game is referenced by
// two Teams  (home and away).  If one Team is deleted, then there shouldn't be a game
// anymore and that game should be removed from the other Team's list of games.  Why
// doesn't CascadeType.ALL do this?
*/

@Entity
@Table(name="teams")
public class Team extends NamedEntity {
   private Set<Game> games = new HashSet<Game>();
   
   @OneToMany(cascade = CascadeType.ALL)
    @JoinTable(
        name="teams_games",
        joinColumns = @JoinColumn( name="team"),
        inverseJoinColumns = @JoinColumn( name="game")
    )
   public Set<Game> getGames() {
      return games;
   }
   public void setGames(Set<Game> games) {
      this.games = games;
   }

}


@Entity
@Table(name="games")
public class Game extends NamedEntity {
   private Team home;
   private Team away;

   @ManyToOne
    @JoinColumn(name = "home")
   public Team getHome() {
      return home;
   }
   public void setHome(Team home) {
      this.home = home;
   }

    @ManyToOne
    @JoinColumn(name = "away")
   public Team getAway() {
      return away;
   }
   public void setAway(Team away) {
      this.away = away;
   }

}


Top
 Profile  
 
 Post subject: Re: Cascading delete
PostPosted: Wed Aug 26, 2009 7:13 pm 
Beginner
Beginner

Joined: Fri Mar 21, 2008 8:07 pm
Posts: 23
I got a response on IRC #hibernate regarding this issue, but still have some questions. Here is what sebersole said (he logged off before I could respond):

[2009-08-26, 14:44] sebersole: tauren: i am trying to understand a few things. like first, why do you map this through a join table?
[2009-08-26, 14:45] sebersole: and then on the other side (Game - Team) you do not
[2009-08-26, 14:47] sebersole: also, you do not define the association properly as bi-directional
[2009-08-26, 14:47] sebersole: i am not overly familiar with the annotations, so not exactly sure what that would look like here
[2009-08-26, 14:49] sebersole: but then lastly you dont define any cascading..
[2009-08-26, 14:51] sebersole: i think you'd really have to map 2 collections on Team: homeGames and awayGames
[2009-08-26, 14:57] sebersole: anyway...
[2009-08-26, 14:57] sebersole: the only 2 options I see are:
[2009-08-26, 14:57] sebersole: 1) map the home/away distinction
[2009-08-26, 14:59] sebersole: 2) separate the notion of a Game and a Participant where a Participant is a Team+home/away indicator (in table terms you'd have Participant (game_id, team_id, home_away_indicator, ... ) where the first three columns make up a unique key

First of all, I believe that the JoinTable on the Team side is probably a left-over mistake on my end. I'm a little confused on the best way to map this relationship and had been trying several approaches. I was unsure how to make it bi-directional as well.

I'm not sure what sebersole means by not defining any cascading. Isn't that what @OneToMany(cascade=CascadeType.ALL) is for?

I totally agree that one of his two solutions are probably the right approach. But I have concerns with both of them:

1. Map home and away separately.
This would mean that a Team would have Set<Game> homeGames and Set<Game> awayGames.

My concern with this approach is how to get a list of all of a Team's games. If I need to print a schedule ordered by Game.startTime, how would I get a list of all of a Team's games if they are split across two collections (home/away)? I want a hibernate query to get the full sorted list, I don't want to use Java to combine the lists.

2. Add a Participant entity between Team and Game.
Thus a Team would have a Set<Participant> gameParticipations and Game would have a Set<Participant> teamParticipants. Then Participant would have Team team, Game game, and boolean home.

But in this case, I'm still unclear on how to delete a Team and all its Games. If I delete a Team, the associated Participants would be deleted. But how do I then cascade that further to delete the Game and the Set<Participant> teamParticipants in the Game, but not also delete the other Team? I only want to delete one Team, its Participants, its Games, and other Participants in each Game, but not the Teams that the other Participants refer to.

I'd like either of these two solutions to work with just a simple delete(team) call. I don't want to have to manually manage the deletions.

Thanks in advance for the help!
Tauren


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.