-->
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: CompositeID with ManyToOne
PostPosted: Sun Mar 04, 2007 11:57 am 
Newbie

Joined: Sun Feb 25, 2007 1:35 pm
Posts: 5
Hello everybody,

I've got a little problem using composite ID when refering in a ManyToOne association.
In my application there are sites where the ID consists only of the name:

Code:
@Entity
public class PokerSite {

   @Id
   private String siteName;
   
   public String getSiteName() {
      return siteName;
   }
   
   public void setSiteName(String siteName) {
      this.siteName = siteName;
   }

   private PokerSite() {}
   
   public PokerSite(String siteName) {
      this.siteName = siteName;
   }

   // implementation of hashcode and equals
}


Then I have a player who's ID is a composite of her name and the site she's playing on:

Code:
@Entity
@IdClass(de.scumm.pokertool.core.model.PlayerId.class)
public class Player implements Serializable {
   private static final long serialVersionUID = 7947461531672383035L;
   public static final Player UNKNOWN = new Player("N/A", new PokerSite("unknown Site"));

   @Id
   private String name;

   @Id
   @ManyToOne(targetEntity=de.scumm.pokertool.core.model.PokerSite.class, cascade = {CascadeType.ALL})
      @JoinTable(name="Person_Site",
         joinColumns={@JoinColumn(name="name")})
   private PokerSite site;

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

   public PokerSite getSite() {
      return site;
   }
   
   public void setSite(PokerSite site) {
      this.site = site;
   }
   
   /* constructor  */
   
   private Player() {}
   
   public Player(String name, PokerSite site) {
      this.name = name;
      this.site = site;
      
   }

   // implementation of hashcode and equals
}


with the following IdClass

Code:
public class PlayerId implements Serializable {
   private static final long serialVersionUID = -5365195885916675825L;

   private String name;

   @ManyToOne(targetEntity=de.scumm.pokertool.core.model.PokerSite.class, cascade = {CascadeType.ALL})
      @JoinTable(name="Person_Site",
         joinColumns={@JoinColumn(name="name", insertable=false, updatable=false)})
   private PokerSite site;

   public String getName() {
      return name;
   }

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

   public PokerSite getSite() {
      return site;
   }

   public void setSite(PokerSite site) {
      this.site = site;
   }
   
   @Override
   public boolean equals(Object o) {
      if (o instanceof Player) {
         Player otherPlayer = (Player)o;
         return name.equals(otherPlayer.getName())
            && site.equals(otherPlayer.getSite());
      }
      return false;
   }
   
   @Override
   public int hashCode() {
      return (name).hashCode();
   }
}


I now try to create an action for a player in which the Player is not even a ID such as the following:

Code:
@Entity
public class Action {

   // some constants defined up here

   @Id @GeneratedValue
   private Long id;
   
(targetEntity=de.scumm.pokertool.core.model.Player.class, cascade={CascadeType.ALL})
   @JoinTable(name="Action_Player",
         joinColumns={@JoinColumn(name="action")},
         inverseJoinColumns={@JoinColumn(name="name"), @JoinColumn(name="site")})(name="site")})
   private Player player;
   
   private String type;

   private float value;
   
   public Action() {}
   
   public Long getId() {
      return id;
   }

   @SuppressWarnings("unused")
   private void setId(Long id) {
      this.id = id;
   }
   
   public Player getPlayer() {
      return player;
   }

   public void setPlayer(Player player) {
      this.player = player;
   }

   public String getType() {
      return type;
   }

   public void setType(String type) {
      this.type = type;
   }

   public float getValue() {
      return value;
   }

   public void setValue(float value) {
      this.value = value;
   }

   // some more functions...

}


When I try to persist an Action with Person set and within the Person a valid site I get the following Exception:
Code:

org.hibernate.AnnotationException: A component cannot hold properties split into 2 different tables: de.scumm.pokertool.core.model.Player.id
   at org.hibernate.cfg.ComponentPropertyHolder.addProperty(ComponentPropertyHolder.java:43)
   at org.hibernate.cfg.AnnotationBinder.bindManyToOne(AnnotationBinder.java:1808)
   at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1260)
   at org.hibernate.cfg.AnnotationBinder.fillComponent(AnnotationBinder.java:1671)
   at org.hibernate.cfg.AnnotationBinder.bindId(AnnotationBinder.java:1704)
   at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:663)
   at org.hibernate.cfg.AnnotationConfiguration.processArtifactsOfType(AnnotationConfiguration.java:452)
   at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:268)
   at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1286)
...


I'm not to sure where to start to get around this problem. Obviously I try to avoid to save a player over and over again but as the two person can play with the same name on different sites I'll have to take the site into account as well to generate the ID for a player.

I'm not sure how to resolve this problem and any help would be appreciated.

Thanks everone,


Marc


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.