-->
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.  [ 5 posts ] 
Author Message
 Post subject: How would you collection/map this Map? Any ideas? thanks
PostPosted: Tue Apr 17, 2007 4:25 pm 
Beginner
Beginner

Joined: Thu Feb 26, 2004 11:45 am
Posts: 46
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version:3.2.1

I'm trying to figure out a straightforward way of mapping a class with a composition to another class using a HashMap.
Seems straight forward, but i'm having a little problem.

Consider Company maintains a collection of Branches, keyed by the BranchName;
I would like to map this in such a way that there should only be 2 tables, Company and Branch.
The Branch Table may or may not need it's own synthetic key, i can certainly see a key consisting of
CompanyID,BranchName being unique, and of course used to establish the Map. The CompanyId could also serve
as the one-to-one reference from the Branch back to the Company.

I've got something working with the collection mapping looking like below. However, the branch table has it's own ID, which really isn't necessary. What
I'd rather is that the CompanyID,BranchName is the key, and the map is loaded using them.

Am i missing something? or is this really very exotic?


Code:
<class name=Company ...>

            <map name="Branches" inverse="true" cascade="all" >
                <key column="companyID" not-null="true" />
                <map-key  type="string" column="BranchName" />
                <one-to-many class="Branch" />
            </map>

</class>

<class name = Branch ...>
      <id name="branchID" type="long">
         <generator class="native"/>
      </id>

      <many-to-one name="company" not-null="true" column="companyID" class="Company"  />

</class>


Code:
class Company{
    private Long companyID;
    private String companyName;
    private String companyOther;
    private Map<String,Branch>branches = new HashMap<String,Branch>();
    private Map<String, Branch> getBranches() {
      return branches;
    }
    private void setBranches(Map<String, Branch> branches) {
      this.branches = branches;
    }
    public void setBranch(Branch branch){
      branches.put(branch.getBranchName(), branch);
      branch.setCompany(this);
    }
    public Branch getBranch(String branchName){
      return branches.get(branchName);
    }
    public Long getCompanyID() {
      return companyID;
    }
    public void setCompanyID(Long companyID) {
      this.companyID = companyID;
    }
    public String getCompanyName() {
      return companyName;
    }
    public void setCompanyName(String companyName) {
      this.companyName = companyName;
    }
    public String getCompanyOther() {
      return companyOther;
    }
    public void setCompanyOther(String companyOther) {
      this.companyOther = companyOther;
    }
   
}
class Branch{
    private Long branchID;
    private String branchName;
    private String branchOther;
    private Company company;
    private Long getBranchID() {
      return branchID;
    }
    public void setBranchID(Long branchID) {
      this.branchID = branchID;
    }
    public String getBranchName() {
      return branchName;
    }
    public void setBranchName(String branchName) {
      this.branchName = branchName;
    }
    public String getBranchOther() {
      return branchOther;
    }
    public void setBranchOther(String branchOther) {
      this.branchOther = branchOther;
    }
    public Company getCompany() {
      return company;
    }
    private void setCompany(Company company) {
      this.company = company;
    }
}



Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 17, 2007 7:18 pm 
Newbie

Joined: Fri Jun 02, 2006 9:31 pm
Posts: 7
What you have seems fine. You just need to set up the natural key of the Branch with a composite-id, then get rid of the synthetic "branchID". Just make sure your table PK includes both columns to guarantee branchNames are unique within a company, and your map should be fine.

Code:
<class name="Company">
    <map name="branches" inverse="true" cascade="all" >
        <key column="companyID" not-null="true" />
        <map-key  type="string" column="branchName" />
        <one-to-many class="Branch" />
    </map>

    ...

</class>

<class name="Branch">
    <composite-id>
        <key-property name="companyID" column="companyID" />
        <key-property name="branchName" column="branchName" />
    </composite-id>

    <many-to-one name="company" not-null="true" column="companyID" class="Company"  update="false" insert="false"/>

    ...

</class>


The only problem is that this requires a "companyId" property on Branch. This is because there are some "limitations" on "key-many-to-one". See http://www.hibernate.org/117.html#A35

But you could try it and see if it works for you:

Code:
<class name="Branch">
    <composite-id>
        <key-many-to-one name="company" column="companyID" />
        <key-property name="branchName" column="branchName" />
    </composite-id>

    ...

</class>

_________________
"Man's Ego is the fountainhead of Human progress..."
(Ayn Rand)


Top
 Profile  
 
 Post subject: key-many-to-one worked great
PostPosted: Wed Apr 18, 2007 12:39 pm 
Beginner
Beginner

Joined: Thu Feb 26, 2004 11:45 am
Posts: 46
Thanks so much. That worked perfectly. Your second alternative key-many-to-one worked great.

thanks again, i appreciate it.


Top
 Profile  
 
 Post subject: cascade="all" is ignored, is it because of this ma
PostPosted: Mon Apr 23, 2007 12:06 pm 
Beginner
Beginner

Joined: Thu Feb 26, 2004 11:45 am
Posts: 46
Company and Branch mapping works great. I've got Company cascading = "all" set just as described

Code:
<class name="Company">
    <map name="branches" inverse="true" cascade="all" >
        <key column="companyID" not-null="true" />
        <map-key  type="string" column="branchName" />
        <one-to-many class="Branch" />
    </map>

    ...

</class>


When i create a company, and add branches, and make the company persistant all works well.

However, if i load a Company, add a Branch, make Company persistent (either implicitly or explicitly), the new Branch is never saved. I've tried all sorts of cascades (in addition to "all")

The only way i can get this to work is to explicity make any branch i add persistent. Am i trying to do something that is not possible?

Specificlly the code below does not result in adding a branch.
Code:
Company c = session.load(new Long(id));
session.saveOrUpdate(c); // this, i think is redundant, but just in case
Branch br = new Branch(branchname);
c.addBranch(br);
session.flush();
session.close();


The only way to get the above branch to be added/inserted is a call to session.saveOrUpdate(br);

Isn't that what cascade is supposed to do for me?


Top
 Profile  
 
 Post subject: cascade="all" requires the connection to be lazy=&
PostPosted: Mon Apr 23, 2007 1:33 pm 
Beginner
Beginner

Joined: Thu Feb 26, 2004 11:45 am
Posts: 46
FWIW

apparently cascading does not work here if the collection is lazy. At least that appears to be what fixed it.

wasn't evident to me.


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