-->
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.  [ 1 post ] 
Author Message
 Post subject: OneToMany with Composite and Foreign Key on Many side Delete
PostPosted: Fri May 14, 2010 5:07 pm 
Newbie

Joined: Fri May 14, 2010 4:34 pm
Posts: 1
Hi, today I've encountered a really tricky issue (at least to me). I'm using hibernate-annotations 3.4.0.GA with hibernate-core 3.3.0.SP1. I am trying to model that kind of relationship: I have Artists and each of this Artist has TopTags. For various reasons I decided to model that as a one to many instead of a many to many relationship. Let's assume for simplicity each artist has the property name, which is also the key and each Tag has a name which is also the key there. Now when using that in a one to many relationship the sets of corresponding Tags need to refer to an artist, therefore I need a composite key: artistname, tagname where artistname is also a foreign key. This results in the following classes:

Artist.class
Code:
@Entity
@Table(name = "`Artists`")
public class Artist {
   
   @Id
   private String name;
   
   @OneToMany(cascade = CascadeType.ALL)
   @JoinColumn(name="artist")
   private List<Tag> tags;

   public Artist() {
   }
   
   public Artist(
         String name
   ) {
      this.name = name;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public List<Tag> getTags() {
      return tags;
   }

   public void setTags(List<Tag> tags) {
      this.tags = tags;
   }

}


Tag:
Code:
@Entity
@Table(name = "`Tags`")
public class TopTag {
   
   @Id
   private TagKey key;
   
   public Tag() {
   }
   
   public TopTag(
         String name,
         Artist artist
   ) {
      this.key = new TagKey();
      this.key.setName(name);
      this.key.setArtist(artist);
   }
   
   public String getName() {
      return this.key.getName();
   }
   
   public void setKey(TagKey key) {
      this.key = key;
   }
   
   public TagKey getKey() {
      return key;
   }

}


TagKey:
Code:
@Embeddable
public class TagKey implements Serializable {
   
   private static final long serialVersionUID = 4318615867062316407L;
   
   private String name;
   
   @ManyToOne
   @JoinColumn(
         name = "artist",
         insertable = false,
         updatable = false
      )
   private Artist artist;

   public void setName(String name) {
      this.name = name;
   }

   public String getName() {
      return name;
   }

   public void setArtist(Artist artist) {
      this.artist = artist;
   }

   public Artist getArtist() {
      return artist;
   }

   @Override
   public int hashCode() {
      [...]
   }

   @Override
   public boolean equals(Object obj) {
      [...]
   }

}


Select and insert works fine. But deleting an entry from the collection fails. Let's assume the following transaction where the Tags for Artist Deftones are already set:
Code:
Artist artist = (Artist) session.createQuery(
    "FROM Artist artist "
    + "WHERE artist.name = :name"
  ).setString("name", "Deftones").uniqueResult();
artist.getTags().remove(0);


Now this will result in the following error:
Code:
org.hibernate.exception.SQLGrammarException: could not delete collection rows: [test.package.Artist.tags#Deftones]; SQL [update `Tags` set artist=null where artist=? and artist=? and `name`=?];
[...]
Caused by: java.sql.SQLException: No value specified for parameter 3


I've ommited the rest of the stack trace as there is not anything else important. Obiously hibernate shouldn't update the corresponding row and set artist to null but delete the row. Does anyone have an idea what's going wrong? Please get back to me if anything remained unclear.
(I had to adjust the code snippets as they were coming out of a larger context, hopefully I haven't made any errors, I've also ommited the "obvious" annotations for columns etc., as you might have noticed I am annotating fields instead of accessors).

Thanks!


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

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.