-->
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.  [ 4 posts ] 
Author Message
 Post subject: Complex, multiple foreign keys in one field
PostPosted: Fri Feb 20, 2009 9:24 am 
Beginner
Beginner

Joined: Thu Feb 19, 2009 5:48 am
Posts: 37
Location: Glasgow, Scotland
Like I've said in previous posts. I have an Event class that has a field containing a comma separated list of Resource names. Each of these names should link to a row in the Resource table.
So when an Event is saved with it's Resource list, the event should be stored (in the Event table), all of the Resource(s) stored (in the Resource table) and the name of each resource added (as a comma separated list) to the resource field of the corresponding Event row.

Can this be don in Hibernate?!?? ...and how?

Mapping documents:
Code:
<hibernate-mapping>
    <class name="Event" table="EVENTS" mutable="false">
        <id name="id" column="EVENT_ID" unsaved-value="-1">
            <generator class="increment"/>
        </id>
       
        <property name="date" type="timestamp" column="EVENT_DATE"/>
        <property name="title"/>
       
      <set name="clients" cascade="save-update" table="CLIENTS" >
         <key column="EVENT_ID" />
         <one-to-many class="Client" />
      </set>
      
        <property name="requiredResources" type="ResourcesUserType" column="resourceNames" />
        <!--  how do I get this to create/update/retrieve resource rows in the database -->

    </class>
</hibernate-mapping>

    <class name="Resource" table="Resource" mutable="false">
        <id name="id" column="RESOURCE_ID" unsaved-value="-1">
            <generator class="increment"/>
        </id>
        <property name="name"/>
    </class>


_________________
##############################
If I helped, rate my comment, I have plenty of stupid questions to ask that I need credit for ;)
##############################


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 20, 2009 9:36 am 
Regular
Regular

Joined: Fri Jan 30, 2009 10:10 am
Posts: 74
Location: London
Why does your requiredResources field need to be a comma separated list of resource names?

Do you want hibernate to look after ensuring referential integrity is preserved? (i.e. your list must never name a resource that does not exist).

--
Stephen Souness


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 20, 2009 10:15 am 
Beginner
Beginner

Joined: Thu Feb 19, 2009 5:48 am
Posts: 37
Location: Glasgow, Scotland
It's a legacy system so it's the way it's done, to change it now would mess up the old systems running. RI isn't really a big deal, there are plenty of safeguards in the code but if there's a simple way of also doing that it would be nice :D
Any idea how it could be done?

_________________
##############################
If I helped, rate my comment, I have plenty of stupid questions to ask that I need credit for ;)
##############################


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 20, 2009 12:32 pm 
Beginner
Beginner

Joined: Thu Feb 19, 2009 5:48 am
Posts: 37
Location: Glasgow, Scotland
Can't anyone help with this? I want the effect of this which returns a comma separated list of the resource names...

Code:
<property name="requiredResources" type="ResourcesUserType" column="resourceNames" />


...but also with the effect of something like...

Code:
<set name="requiredResources" cascade="save-update" table="RESOURCE">
   <key column="RESOURCE_ID" />
   <one-to-many class="Resource" />
</set>


The ResourceUserType looks like

Code:
public class ResourcesUserType implements UserType {

   @Override
   public Object assemble(Serializable arg0, Object arg1)
         throws HibernateException {
      return arg0;
   }

   @Override
   public Object deepCopy(Object arg0) throws HibernateException {
      return arg0;
   }

   @Override
   public Serializable disassemble(Object arg0) throws HibernateException {
      return (Serializable)arg0;
   }

   @Override
   public boolean equals(Object x, Object y) throws HibernateException {
      return (x == null) ? (y == null) : x.equals(y);
   }

   @Override
   public int hashCode(Object arg0) throws HibernateException {
      return ((Resource)arg0).hashCode();
   }

   @Override
   public boolean isMutable() {
      return false;
   }

   @Override
   public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
         throws HibernateException, SQLException {
      String rResources = (String)Hibernate.STRING.nullSafeGet(rs, names[0]);//rs.getNString("resourceNames");
     
      ArrayList<Resource> returnedResources = new ArrayList<Resource>();
     
      for (String r : rResources.split(",")){
         Resource resource = new Resource();
         resource.setName(r.trim());
         returnedResources.add(resource);
      }     
      return returnedResources.toArray();
   }

   @SuppressWarnings("unchecked")
   @Override
   public void nullSafeSet(PreparedStatement st, Object value, int index)
         throws HibernateException, SQLException {
     
      /*DEBUG*/System.out.println("Object Value: "+value);
     
      if (value == null)
         throw new IllegalArgumentException( "Received object in nullSafeSet was null - " + returnedClass() );

      if (!(value instanceof Set
            && (((Set)value).iterator().next()) instanceof Resource)){
         throw new IllegalArgumentException( "Received object in nullSafeSet was " + value.getClass().getName() + " in " + returnedClass() );
      }
           
      String resources="";
      if (value == null) {
         st.setString(index, "");
       } else {
          //Build the comma separated lists for database
             for (Resource r : (Set<Resource>)value){//if this is not a set of resources, the exception would have been thrown already
                resources+=r.getName()+",";
             }
          //remove the additional comma
             resources=resources.substring(0,(resources.length()-1));
       }
      Hibernate.STRING.nullSafeSet(st, resources, index);
   }

   @Override
   public Object replace(Object arg0, Object arg1, Object arg2)
         throws HibernateException {
      return arg0;
   }

   @Override
   public Class returnedClass() {
      return Resource[].class;
   }

   @Override
   public int[] sqlTypes() {
      return new int[] {Hibernate.STRING.sqlType()};
   }

}

_________________
##############################
If I helped, rate my comment, I have plenty of stupid questions to ask that I need credit for ;)
##############################


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.