-->
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: duplicate key SQL error in unary association class insert
PostPosted: Wed Oct 10, 2007 11:38 am 
Newbie

Joined: Sun Jul 23, 2006 8:48 am
Posts: 6
Hello.

I have modeled a unary (singular) association on my entity ContentProviderAccount with an association class
(implemented as a join/link table).

My use case is that each ContentProviderAccount entity has a list of fans and a list of favorites (which are ContentProviderAccount entities as well)

ContentProviderAccount A can add ContentProviderAccount B as a favorite (A is then B's fan).
Also, ContentProviderAccount B can add ContentProviderAccount A as a favorite (B is then A's fan).

The association is not necessarily mutual and two associations can exist between two ContentProviderAccounts.

Each association has a creation date and a number (not suitable as a primary key though, because it is not unique)



This is my implementation of the assocoation class: (inspired by listing 7.1 in the book 'Java persistence with Hibernate', chapter 7.2.3)

Code:
@javax.persistence.Entity
@javax.persistence.Table(name = "FANS2FAVORITES")
public class FanFavoriteAssociation implements java.io.Serializable, Comparable<FanFavoriteAssociation> {
   @Embeddable
   public static class Id implements Serializable {
      @Column(name = "CONTENT_PROVIDER_ACCOUNT_FAN_ID")
      private Long fan;

      @Column(name = "CONTENT_PROVIDER_ACCOUNT_FAVORITE_ID")
      private Long favorite;

      public Id() {
      }

      public Id(Long fanId, Long favoriteId) {
         this.fan = fanId;
         this.favorite = favoriteId;
      }

      //equals and hashCode

   }


   @javax.persistence.Column(name = "CREATION_DATE")
   private java.util.Date creationDate;

   @javax.persistence.Column(name = "NUMBER")
   private java.lang.Long number;

   @EmbeddedId
   private Id id = new Id();


   // --------- Relationship Definitions -----------

   @javax.persistence.ManyToOne
   @javax.persistence.JoinColumn(name = "CONTENT_PROVIDER_ACCOUNT_FAN_ID", insertable = false, updatable = false)
   private ContentProviderAccount contentProviderAccountFan;

   @javax.persistence.ManyToOne
   @javax.persistence.JoinColumn(name = "CONTENT_PROVIDER_ACCOUNT_FAVORITE_ID", insertable = false, updatable = false)
   private ContentProviderAccount contentProviderAccountFavorite;


   public FanFavoriteAssociation() {
   }

   public FanFavoriteAssociation(java.util.Date creationDate, java.lang.Long number) {
      setCreationDate(creationDate);
      setNumber(number);
   }

   public FanFavoriteAssociation(ContentProviderAccount contentProviderAccountFan,
         ContentProviderAccount contentProviderAccountFavorite, java.util.Date creationDate, Long number) {
      this.contentProviderAccountFan = contentProviderAccountFan;
      this.contentProviderAccountFavorite = contentProviderAccountFavorite;
      this.creationDate = creationDate;
      this.number = number;

      // set identifier values
      this.id.fan = contentProviderAccountFan.getId();
      this.id.favorite = contentProviderAccountFavorite.getId();

      // guarantee referential integrity
      
       System.out.println("guarantee referential integrity on fans");
       contentProviderAccountFan.getFans().add(this); contentProviderAccountFan.getFavorites().add(this);
       System.out.println("guarantee referential integrity on favorites");
       contentProviderAccountFavorite.getFavorites().add(this);
       contentProviderAccountFavorite.getFans().add(this);
      
      // getter and setter methods
   }

   
   // getters and setters...

   // equals and hashCode...

   // toString and compareTo...

}


the entity ContentProviderAccount has a OneToMany collection for fans and for favorites.

Code:
@javax.persistence.OneToMany(mappedBy = "contentProviderAccountFan")
    public java.util.List<FanFavoriteAssociation> getFans()
    {
        return this.fans;
    }

@javax.persistence.OneToMany(mappedBy = "contentProviderAccountFavorite")
    public java.util.List<FanFavoriteAssociation> getFavorites()
    {
        return this.favorites;
    }



I create an association where userA is fan to userB by doing:

Code:
FanFavoriteAssociation fan2favorite = new FanFavoriteAssociation(userA, userB, new java.util.Date(System.currentTimeMillis()), number);
fanFavoriteAssociationDao.create(fan2favorite);


this conceptually means that userA now is fan to userB and userB is favorite to userA.


This is all well except for when I want to add another association with the opposite case (which is perfectly ok in my concept model).
namely when userB is fan to userA.

This results in a duplicate key SQL error because hibernate tries to create a row with the same values (which is strange becuase I reverse the parameters to the fanfavoriteassociation constructor).

column A(pk) column B(pk)
1 2
2 1

These two table rows should not result in duplicate keys, right?

With a manual insert sql query this works well but Hibernate fails (i think in the dao where I call create on the entity manager).

Is this association class insufficient for this requirement or have I missed something obvious?


thanks in advice,

Fredrik


Top
 Profile  
 
 Post subject: [SOLVED]
PostPosted: Thu Oct 11, 2007 12:40 pm 
Newbie

Joined: Sun Jul 23, 2006 8:48 am
Posts: 6
Problem fixed. My modeling was correct but somehow my test was wrong but in my service class it works like a charm.


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.