-->
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.  [ 9 posts ] 
Author Message
 Post subject: Help with relation in Hibernate
PostPosted: Tue Jul 31, 2007 8:10 am 
Newbie

Joined: Mon Jul 30, 2007 10:12 pm
Posts: 13
Location: Orust/Sweden
I have a problem with relationship in Hibernate.
A Customer can have many markets and languages.
A Market can have many Languages

Code:
Customer customer = new Customer( "Test" );

Market sweden = new Market( "SE" );
Market canada = new Market( "CA" );

Language swedish = new Language( "SV" );
Language french = new Language( "FR" );
Language english = new Language( "EN" );

sweden.addLanguage( swedish );

canada.addLanguage( french );
canada.addLanguage( english );

Customer.add ?



Hope you understand my psydo code. The sweden market is connected to the
swedish language. The canada Market is connected to the french and english language.

How do I connect a Customer to one or more market with one or more language
Customer can have the sweden market and the swedish language and the canada
market , english language but not nessasary the french language?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 31, 2007 8:43 am 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
Sounds like customer should have a relationship to market and a separate relationship to language.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 31, 2007 10:17 am 
Newbie

Joined: Mon Jul 30, 2007 10:12 pm
Posts: 13
Location: Orust/Sweden
thatmikewilliams wrote:
Sounds like customer should have a relationship to market and a separate relationship to language.


Can you please eleborate. How can I create this relationships so that my first post fullfill it's criteria?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 31, 2007 11:03 am 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
customer.addMarket(sweden);
customer.addMarket(canada);
customer.addLanguage(swedish);
customer.addLanguage(english);

Code:
<class name="Customer" table="customer">
  <set name="languages">
    <key column="customer_id"/>
    <one-to-many class="Language"/>
  </set>

  <set name="markets">
    <key column="customer_id"/>
    <one-to-many class="Market"/>
  </set>
</class>


Code:
public class Customer {
  private Set languages;
  private Set markets;

  public void addLanguage(Language lang) {
    if (languages == null) {
      languages = new HashSet();
    }
    languages.add(lang);
  }

  public Set getLanguages() {
    return languages;
  }

  public void setLanguages(Set langs) {
    languages = langs;
  }

  // same for markets
}


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 31, 2007 11:37 am 
Newbie

Joined: Mon Jul 30, 2007 10:12 pm
Posts: 13
Location: Orust/Sweden
This doesn't actually solv my problem. I can add a language to the customer that isn't suppose to be there. I can have a market that isn't connected to the language.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 31, 2007 11:55 am 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
These rules can't be implemented in hibernate or the database. You need to write java code to enforce this - either in Customer's implementation or, due to the chicken and egg nature of your constraint, in an object builder class that verifies the markets and languages before returning a valid Customer.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 31, 2007 12:00 pm 
Newbie

Joined: Mon Jul 30, 2007 10:12 pm
Posts: 13
Location: Orust/Sweden
Ok! If I had done this in pure SQL with stored procedure I had a Customer table. A Market table, a Language table.

A MarketToLanguages and a CustomerToMarketsToLanguages table. But I get it. I will do this in the Customer implementation.


Problem is that it isn't just java that can retrieve data from the db. We use php because we have a lot of old systems.

Thanks for the replies.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 31, 2007 5:32 pm 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
Right, finally I understand what you're after. Actually you can map this in the way you described by creating an entity for the mapping table between markets and languages. Then, a separate mapping table between customers and market-to-language entities.

Here's the sample code. I've used surrogate primary keys for the mapping tables but you could just as well use a composite if it suits your php needs better.

Customer.java
Code:
package test.mappingentity;

import java.util.ArrayList;
import java.util.List;

public class Customer {
   private Long id;
   private List<MarketToLanguage> marketsToLanguages;

   public Long getId() {
      return id;
   }

   public void setId(Long id) {
      this.id = id;
   }

   public List<MarketToLanguage> getMarketsToLanguages() {
      return marketsToLanguages;
   }

   public void setMarketsToLanguages(List<MarketToLanguage> marketsToLanguages) {
      this.marketsToLanguages = marketsToLanguages;
   }

   public void add(MarketToLanguage marketToLanguage ) {
      if (marketsToLanguages == null) {
         marketsToLanguages = new ArrayList();
      }
      marketsToLanguages.add(marketToLanguage);
   }
}


Customer.hbm.xml
Code:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="test.mappingentity">

<class name="Customer" table="mappingentity_Customer">
   
   <id name="id">
      <generator class="native" />
   </id>

   <bag name="marketsToLanguages"
        table="mappingentity_CustomerToMarketToLanguages"
        cascade="all-delete-orphan">
      <key column="CustomerId"/>
      <many-to-many column="MarketToLanguageId" class="MarketToLanguage"/>
   </bag>
     
</class>
</hibernate-mapping>


Language.java
Code:
package test.mappingentity;

public class Language {
   private Long id;
   private String language;

   public Language() {}
   
   public Language(String language) {
      this.language = language;
   }
   
   public Long getId() {
      return id;
   }

   public void setId(Long id) {
      this.id = id;
   }

   public String getLanguage() {
      return language;
   }

   public void setLanguage(String language) {
      this.language = language;
   }
}


Language.hbm.xml
Code:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="test.mappingentity">

<class name="Language" table="mappingentity_Language">
   
   <id name="id">
      <generator class="native" />
   </id>

   <property name="language"/>
     
</class>
</hibernate-mapping>


Market.java
Code:
package test.mappingentity;

import java.util.ArrayList;
import java.util.List;

public class Market {

   private Long id;
   private String name;
   private List<Language> languages;

   public Market() {}
   public Market(String name) {
      this.name = name;
   }
   
   public Long getId() {
      return id;
   }

   public void setId(Long id) {
      this.id = id;
   }

   public List<Language> getLanguages() {
      return languages;
   }

   public void setLanguages(List<Language> languages) {
      this.languages = languages;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }

   public void addLanguage(Language language) {
      if (languages == null) {
         languages = new ArrayList<Language>();
      }
      languages.add(language);
   }
   
}


Market.hbm.xml
Code:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="test.mappingentity">

<class name="Market" table="mappingentity_Market">
   
   <id name="id">
      <generator class="native" />
   </id>

   <property name="name"/>
   
<!-- Declare this relationship as many-to-many so hibernate uses the join table but specify unique="true" to make it a one-to-many. See hibernate ref doc section 7.3. Unidirectional associations with join tables
-->
   <bag name="languages" table="mappingentity_MarketToLanguages">
      <key column="MarketId"/>
      <many-to-many column="LanguageId" class="Language" unique="true"/>
   </bag>
     
</class>
</hibernate-mapping>


MarketToLanguage.java
Code:
package test.mappingentity;

public class MarketToLanguage {

   private Long id;
   private Market market;
   private Language language;

   public MarketToLanguage() {}
   public MarketToLanguage(Market market, Language language) {
      this.market = market;
      this.language = language;
   }
   
   public Long getId() {
      return id;
   }

   public void setId(Long id) {
      this.id = id;
   }

   public Market getMarket() {
      return market;
   }

   public void setMarket(Market market) {
      this.market = market;
   }

   public Language getLanguage() {
      return language;
   }

   public void setLanguage(Language language) {
      this.language = language;
   }
}


MarketToLanguage.hbm.xml
Code:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="test.mappingentity">

<class name="MarketToLanguage" table="mappingentity_MarketToLanguages">
   
   <id name="id">
      <generator class="native" />
   </id>

   <many-to-one name="market" column="MarketId"/>
   <many-to-one name="language" column="LanguageId"/>
     
</class>
</hibernate-mapping>


TestIt.java
Code:
package test.mappingentity;

import junit.framework.TestCase;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

public class TestIt extends TestCase {

   public void testCreateCustomer() {
      Session s = HibernateUtil.getSession();
      s.beginTransaction();
      
      Language swedish = new Language( "SV" );
      s.save(swedish);
      Language french = new Language( "FR" );
      s.save(french);
      Language english = new Language( "EN" );
      s.save(english);
      
      Market sweden = new Market( "SE" );
      sweden.addLanguage(swedish);
      s.save(sweden);
      Market canada = new Market( "CA" );
      canada.addLanguage(french);
      canada.addLanguage(english);
      s.save(canada);

      Customer customer = new Customer();
      // Create link to sweden/swedish and canada/english
      customer.add(findMarketToLanguage(s, sweden, swedish));
      customer.add(findMarketToLanguage(s, canada, english));
      s.save(customer);
      
      s.getTransaction().commit();
      s.close();
   }

   private MarketToLanguage findMarketToLanguage(Session s, Market market, Language language) {
      Criteria criteria = s.createCriteria(MarketToLanguage.class);
      criteria.add(Restrictions.eq("market", market))
      .add(Restrictions.eq("language", language));
      return (MarketToLanguage)criteria.uniqueResult();
      
   }
}


HibernateUtil.java
Code:
package test.mappingentity;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;


public class HibernateUtil {

    private static SessionFactory factory;

    static {
       Configuration config = new Configuration()
          .addClass(Language.class)
          .addClass(Market.class)
          .addClass(Customer.class)
          .addClass(MarketToLanguage.class)
// HSQLDB Config
          .setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect")
         .setProperty("hibernate.connection.driver_class", "org.hsqldb.jdbcDriver")
         .setProperty("hibernate.connection.url", "jdbc:hsqldb:mem:test")
          .setProperty("hibernate.connection.username", "sa")
          .setProperty("hibernate.connection.password", "")
          .setProperty("hibernate.hbm2ddl.auto", "create-drop")
          
// MYSQL Config
//          .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect")
//         .setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver")
//         .setProperty("hibernate.connection.url", "jdbc:mysql://localhost/test")
//         .setProperty("hibernate.connection.username", "root")
//         .setProperty("hibernate.connection.password", "password")
//         .setProperty("hibernate.hbm2ddl.auto", "create-drop")
                  
         .setProperty("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider")
         .setProperty("hibernate.show_sql", "true");
        HibernateUtil.setSessionFactory(config.buildSessionFactory());
    }

    public static synchronized Session getSession() {
        if (factory == null) {
            factory = new Configuration().configure().buildSessionFactory();
        }
        return factory.openSession();
    }

    public static void setSessionFactory(SessionFactory factory) {
        HibernateUtil.factory = factory;
    }
}


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 01, 2007 5:51 pm 
Newbie

Joined: Mon Jul 30, 2007 10:12 pm
Posts: 13
Location: Orust/Sweden
That did it! Thanks a lot!


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