-->
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: many-to-many-to-many?
PostPosted: Wed Sep 15, 2004 6:49 pm 
Newbie

Joined: Wed Sep 15, 2004 4:54 pm
Posts: 1
I've read the documentation, FAQs, and the relevant parts of Hibernate in Action, many times now. I've been searching the forums, but I haven't found anyone who's described this type of problem. To be fair, finding the right search terms has been a challenge. Every search that sounds relevant brings back a million posts.

Here's a simplified case of my problem.

A user logs in, makes their way through authentication, and the application looks up what they have access to:

Code:
CREATE TABLE User_Access (
  User_Access_ID int(11) NOT NULL auto_increment,
  Username varchar(64),
  Access_To_What varchar(64),
  Generic_Name varchar(64),
  PRIMARY KEY  (User_Access_ID),
  UNIQUE KEY SingleSignOn (Username,Access_To_What)
);


Each Username might have access to many things. Each record of User_Access might have the same Generic_Name, or they might all be different.

Code:
CREATE TABLE Generic (
  Generic_ID int(11) NOT NULL auto_increment,
  Generic_Name varchar(64),
  Code varchar(16),
  Name varchar(64),
  PRIMARY KEY (Generic_ID),
  UNIQUE KEY NameAndCode (Generic_Name,Code)
);


Here's an example for Bob:

Username = "Bob", Access_To_What = "Section1", Generic_Name = "DEFAULT"
Username = "Bob", Access_To_What = "Section2", Generic_Name = "DEFAULT"

And the data for DEFAULT:

Generic_Name = "DEFAULT", Code = "codeA", Name = "Red"
Generic_Name = "DEFAULT", Code = "codeB", Name = "Green"
Generic_Name = "DEFAULT", Code = "codeC", Name = "Blue"

I have tried....lots of different ways of trying to get this to map. The problem is there's no nice clean mapping between User_Access_ID and Generic_ID. There's no association table, just Generic_Name.

Mapping for User_Access:
Code:
<hibernate-mapping package="db">
  <class name="UserAccess" table="User_Access">
    <id
      column="User_Access_ID"
      name="UserAccessId"
      type="integer"
    >
      <generator class="identity" />
    </id>

    <property
      column="Username"
      length="64"
      name="Username"
      not-null="true"
      type="string"
     />

    <property
      column="Access_To_What"
      length="64"
      name="Username"
      not-null="true"
      type="string"
     />

    <set name="Generics" table="Generic">
      <key column="Generic_Name"/>
      <many-to-many class="Generic"/>
    </set>

  </class>
</hibernate-mapping>


And the mapping for Generic:
Code:
<hibernate-mapping package="db">
  <class name="Generic" table="Generic">
    <id
      column="Generic_ID"
      name="GenericId"
      type="integer"
    >
      <generator class="identity" />
    </id>

    <property
      column="Generic_Name"
      name="GenericName"
      not-null="true"
      type="string"
      length="64"
    />
    <property
      column="Code"
      name="Code"
      not-null="true"
      type="string"
      length="16"
    />
    <property
      column="Name"
      length="64"
      name="Name"
      not-null="true"
      type="string"
     />
  </class>
</hibernate-mapping>


Hibernate version: 2.1.6
MySQL version: 4.0.21

Code between sessionFactory.openSession() and session.close():

I haven't included the User mapping or table, or any of the real names for things or all the other crap in these tables. I know I tend to get glassey eyed and move on when I see too much detail. Anyhow, my goal is something like:

Code:
[...]

User u = [hibernate session.find for mapped User table]

Set useraccess_set = u.getUserAccess();
Iterator useraccess_it = useraccess_set.iterator();

while (useraccess_it.hasNext())
{
    UserAccess ua = (UserAccess)useraccess_it.next();

    Set generics_set = ua.getGenerics();
    Iterator generics_it = generics_set.iterator();

    out.write("Your Generics:");
    while (generics_it.hasNext())
    {
        Generic g = (Generic)generics_it.next();

        out.write(g.getName());
    }
}

[...]


Running that inside a test case produces:

Code:
net.sf.hibernate.MappingException: Foreign key (Generic [elt])) must have same number of columns as the referenced primary key (Generic [Generic_Name,elt])
  at net.sf.hibernate.mapping.ForeignKey.setReferencedTable(ForeignKey.java:60)
  at net.sf.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:691)
  at net.sf.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:666)
  at net.sf.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:784)
  at com.metrixmatrix.test.Main.main(Main.java:47)
Exception in thread "main"


I really apologize if this has been covered a thousand times. I'm really hoping for one of three outcomes:
1) You stink, I do this all the time, here's how.
2) You stink, Hibernate doesn't do this because it's not supposed to.
3) You stink, here let me shoot you and put you out of your misery.


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.