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.  [ 10 posts ] 
Author Message
 Post subject: Only one side of bidirectional relation working, why???
PostPosted: Fri May 28, 2004 4:53 pm 
Beginner
Beginner

Joined: Sun May 16, 2004 3:53 pm
Posts: 47
Location: Belo Horizonte, Brazil
Hi,
i've been trying to make this work, but every step i make i get another problem... here it is.

I got two tables, Employee and Organization (many-to-one). I can access the organization through a employee object perfectly, but i cannot access the employees of one organization.

In other words, the following code works.
Code:
  Employee emp10 = (Employee)session.load(Employee.class, new Integer(10));
  System.out.println("Employee name: " + emp10.getLastName() + ", " + emp10.getFirstName());
  Organization org10 = emp10.getOrg();
  System.out.println("Organization of employee: " + org10.getOrgName());


The following code doesn't work, i never get inside the while.
Code:
  Organization organization1 = (Organization)session.load(Organization.class, new Integer(10));
  System.out.println(" organization name: " + organization1.getOrgName());
  Set org10Employees = organization1.getEmployees();
  Iterator it = org10Employees.iterator();
  while (it.hasNext()){
   Employee empOrg10 = (Employee)it.next();
   System.out.println("Employee is: " + empOrg10.getLastName());
}


And employee 10 belongs to organization 10, but it's not returned.

Mapping for Employee.hbm.xml
Code:
        <many-to-one
            name="org"
            class="hibernate.Organization"
            cascade="none"
            outer-join="auto"
            update="true"
            insert="true"
            column="fk_orgId"
        />


Mapping for Organization.hbm.xml
Code:
        <set
            name="employees"
            lazy="true"
            inverse="true"
            cascade="none"
            sort="unsorted"
        >
              <key
                  column="fk_orgId"
              />
              <one-to-many
                  class="hibernate.Employee"
              />
        </set>


Thanks,
ltcmelo


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 28, 2004 8:40 pm 
Beginner
Beginner

Joined: Mon Sep 29, 2003 10:32 pm
Posts: 35
Location: Toronto, Ontario
Your code works fine on my machine, the mappings are fine, so check the data in your tables.


Top
 Profile  
 
 Post subject:
PostPosted: Sat May 29, 2004 7:57 am 
Beginner
Beginner

Joined: Sun May 16, 2004 3:53 pm
Posts: 47
Location: Belo Horizonte, Brazil
I cannot believe this, what could possibly be wrong?

I first thought of this, then i re-created my tables (twice already), and i can't see anything wrong in them.

Well, thanks javamona for your time, if you have an ideia about what could be wrong, please let me know.

Regards,
ltcmelo


Top
 Profile  
 
 Post subject:
PostPosted: Sat May 29, 2004 8:02 am 
Beginner
Beginner

Joined: Sun May 16, 2004 3:53 pm
Posts: 47
Location: Belo Horizonte, Brazil
Just one more thing...
As you said it worked with you, you probably wrote some code (thanks for your time), so, could you post your java persistent classes for me???

I know that the problem might not be there, but as i'm desperate...

Thanks,
ltcmelo


Top
 Profile  
 
 Post subject:
PostPosted: Sat May 29, 2004 9:44 am 
Beginner
Beginner

Joined: Mon Sep 29, 2003 10:32 pm
Posts: 35
Location: Toronto, Ontario
If the data is ont there in the database i.e. there is no Employee with an organization of 10, you won't enter the last while loop.
I have the following data in the database.
Code:
<dataset>
   <ORGANIZATION orgid="10" orgName="TD Waterhouse" orgAddress="14 Kings Way"/>
   <ORGANIZATION orgid="2" orgName="Kings Court" orgAddress="22 Mike Way"/>
   <ORGANIZATION orgid="3" orgName="CIBC" orgAddress="20 Karls Road"/>
   
   <EMPLOYEE empId="1" firstName="Mark" lastName="Brown" fk_orgid="2"/>
   <EMPLOYEE empId="2" firstName="Karen" lastName="James" fk_orgid="2"/>
   <EMPLOYEE empId="3" firstName="Phillip" lastName="Gayle" fk_orgid="2"/>
   <EMPLOYEE empId="4" firstName="Guyan" lastName="Brissett" fk_orgid="10"/>
   <EMPLOYEE empId="10" firstName="Rick" lastName="Dooley" fk_orgid="10"/>
</dataset>


The persistent classes I haven't changed, but here goes anyway
Code:

package hibernate;

import dg.base.BasePersistentObject;

public class Employee extends BasePersistentObject {
    private Integer empId;   
     private String firstName;   
     private String lastName;   
     private Organization org;     

     public Employee(){   }         

     public Employee(Integer id, String fn, String ln, Organization fk){   
            this.empId = id;       
            this.firstName = fn;       
            this.lastName = ln;       
            this.org = fk;   
   }     

   /**   
   *     
   * @hibernate.id   
    *  generator-class="native"   
   *  column="empId"   
   *     
   * @return the id   
   *   
   */   
   public Integer getEmpId() {       
     return empId;   
   }     

   /**   
   *     
    * @hibernate.property   
    *  column="firstName"   
   *     
   * @return   
   *     
   */   
   public String getFirstName() {       
     return firstName;   
   }     

   /**   
   *     
    * @hibernate.many-to-one   
   *  column="fk_orgId"   
   *     
   * @return the organization of the employee   
   *     
   */   
   public Organization getOrg() {       
     return org;   
   }     

   /**   
   *     
   * @hibernate.property   
    *  column="lastName"   
   *     
   * @return   
   *     
   */   
   public String getLastName() {       
      return lastName;   
   }     

   /**   
   * @param integer   
   */   
   public void setEmpId(Integer integer) {       
     empId = integer;   
   }     

   /**   
    * @param string   
   */   
   public void setFirstName(String string) {       
     firstName = string;   
   }     

   /**   
   * @param organization   
   */   
   public void setOrg(Organization fk_orgId) {       
     this.org = fk_orgId;   
   }     

   /**   
    * @param string   
   */   
   public void setLastName(String string) {       
   lastName = string;   
   }

}


Organization:
Code:
public class Organization extends BasePersistentObject {
   
   private Integer orgId;   
   private String orgName;   
   private String orgAddress;   
   private Set employees = new HashSet();     

   public Organization(){   }
      
   public Organization(Integer id, String name, String add){   
               this.orgId = id;       
                   this.orgName = name;       
                   this.orgAddress = add;   
   }                   

//    i also tried inserting table="Employee" under
//   @hibenate.set tag     
   /**   
   *     
   * @hibernate.set   
   *  lazy="false"   
   *  inverse="true"   
   *     
   * @hibernate.collection-key   
   *  column="fk_orgId"   
   * @hibernate.collection-one-to-many   
   *  class="hibernate.Employee"   
   *     
   * @return all the employees   
   *     
   */   
   public Set getEmployees() {       
      return employees;   
   }
      
   /**   
   *     
   * @hibernate.property   
    *  column="orgAddress"   
    *     
   * @return   
   *     
   */   
   public String getOrgAddress() {       
     return orgAddress;   
   }     

   /**   
    *     
   * @hibernate.id   
   *  generator-class="native"   
   *  column="orgId"   
   *     
   * @return   
   */   
   public Integer getOrgId() {       
     return orgId;   
   }     

   /**   
   *     
   * @hibernate.property   
   *  column="orgName"   
   *     
   * @return   
   */   
   public String getOrgName() {       
     return orgName;   
   }     

   /**   
   * @param set   
   */   
   public void setEmployees(Set emps) {       
     employees = emps;   
   }
      
   /**   
   * @param string   
   */   
   public void setOrgAddress(String string) {       
     orgAddress = string;   
   }     

   /**   
   * @param integer   
   */   
   public void setOrgId(Integer integer) {       
   orgId = integer;   
   }     

   /**   
   * @param string   
   */   
   public void setOrgName(String string) {       
     orgName = string;   
   }


}




My test looks like this. The only thing I changed was to use getHibernateTemplate().load instead of session.load() (because I'm using Spring). It shouldn't matter.

Code:
public void printEmployees(int organizationId) {
      Employee emp10 = (Employee)getHibernateTemplate().load(Employee.class, new Integer(10));
        System.out.println("Employee name: " + emp10.getLastName() + ", " + emp10.getFirstName());
        Organization org10 = emp10.getOrg();
        System.out.println("Organization of employee: " + org10.getOrgName());
      
        Organization organization1 = (Organization)getHibernateTemplate().load(Organization.class, new Integer(10));
        System.out.println(" organization name: " + organization1.getOrgName());
        Set org10Employees = organization1.getEmployees();
       
        Iterator it = org10Employees.iterator();
        while (it.hasNext()){
         Employee empOrg10 = (Employee)it.next();
         System.out.println("Employee is: " + empOrg10.getLastName());
      }

      
   }


This is the result of the test. It prints the right employees - Brissett and Dooley
Code:
Hibernate: select employee0_.empId as empId1_, employee0_.firstName as firstName1_, employee0_.fk_orgId as fk_orgId1_, employee0_.lastName as lastName1_, organizati1_.orgId as orgId0_, organizati1_.orgAddress as orgAddress0_, organizati1_.orgName as orgName0_ from Employee employee0_ left outer join Organization organizati1_ on employee0_.fk_orgId=organizati1_.orgId where employee0_.empId=?
Hibernate: select employees0_.empId as empId__, employees0_.fk_orgId as fk_orgId__, employees0_.empId as empId0_, employees0_.firstName as firstName0_, employees0_.fk_orgId as fk_orgId0_, employees0_.lastName as lastName0_ from Employee employees0_ where employees0_.fk_orgId=?
Employee name: Dooley, Rick
Organization of employee: TD Waterhouse
Hibernate: select organizati0_.orgId as orgId0_, organizati0_.orgAddress as orgAddress0_, organizati0_.orgName as orgName0_ from Organization organizati0_ where organizati0_.orgId=?
Hibernate: select employees0_.empId as empId__, employees0_.fk_orgId as fk_orgId__, employees0_.empId as empId0_, employees0_.firstName as firstName0_, employees0_.fk_orgId as fk_orgId0_, employees0_.lastName as lastName0_ from Employee employees0_ where employees0_.fk_orgId=?
organization name: TD Waterhouse
Employee is: Brissett
Employee is: Dooley




The mappings I have left unchanged.

Check the size of org10Employees, then check how many employees in the database have fk_orgid = 10.

Later.[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Sat May 29, 2004 10:37 am 
Beginner
Beginner

Joined: Sun May 16, 2004 3:53 pm
Posts: 47
Location: Belo Horizonte, Brazil
Oh NO !!!! This is completely NOT UNDERSTANDABLE !!!

Please, i made it work now!!!!
I don't know why it wasn't working!
The code for the session bean was inside a method that, before those selects, it created those records that were being accessed. It was creating the records completely fine (the inserts and the "selects" I posted were in the same method).

Here's the whole method.
Code:
                          //  MARK 1
         Integer orgId10 = new Integer(10);
         Organization org1 = new Organization(orgId10, "samsunk", "samsunk street");
         session.save(org1, orgId10);
         session.flush();
         Integer orgId11 = new Integer(11);
         Organization org2 = new Organization(orgId11, "reeblock", "reeblock street");
         session.save(org2, orgId11);
         session.flush();
         Integer empId10 = new Integer(10);
         Employee emp1 = new Employee(empId10, "sam", "miller", org1);
         session.save(emp1, empId10);
         session.flush();
         Integer empId11 = new Integer(11);
         Employee emp2 = new Employee(empId11, "bill", "floyd", org1);
         session.save(emp2, empId11);
         session.flush();
         Integer empId12 = new Integer(12);
         Employee emp3 = new Employee(empId12, "jen", "smith", org2);
         session.save(emp3, empId12);
         session.flush();
         Integer empId13 = new Integer(13);
         Employee emp4 = new Employee(empId13, "harry", "nielsen", org1);
         session.save(emp4, empId13);
         session.flush();
         Integer empId14 = new Integer(14);
         Employee emp5 = new Employee(empId14, "john", "tiler", org1);
         session.save(emp5, empId14);
         session.flush();

                                 // END OF MARK 1


         //selects employer 10 and do things
         Employee emp10 = (Employee)session.load(Employee.class, new Integer(10));
         System.out.println("Employee name: " + emp10.getLastName() + ", " + emp10.getFirstName());
         Organization org10 = emp10.getOrg();
         System.out.println("Organization of employee: " + org10.getOrgName());
         System.out.println("Address of organization: " + org10.getOrgAddress());
         emp10.setFirstName("newFirstName10");
         
         
         
         
         System.out.println("All employess of org 10...");
         List emps = session.find("from Employee as e where e.org = 10");
         Iterator iter = emps.iterator();
         while (iter.hasNext()){
            Employee empOrg10 = (Employee)iter.next();
            System.out.println("Employee is: " + empOrg10.getLastName());
         }
         

                 
                            // MARK 2
         Organization organization1 = (Organization)session.load(Organization.class, new Integer(10));
         System.out.println(" organization name: " + organization1.getOrgName());
         Set org10Employees = organization1.getEmployees();
         Iterator it = org10Employees.iterator();
         while (it.hasNext()){
               Employee empOrg10 = (Employee)it.next();
               System.out.println("Employee is: " + empOrg10.getLastName());
         }
                                // END OF MARK 2


When i executed the method in the following way, i couldn't get inside the loop of MARK 2, in other words, that's why i thought it wasn't working well.

Then, i commented all the code inside MARK 1, wich does all inserting.
Everything worked perfectly now!!!

So, what is my TERRIBLE MISTAKE????
I can't understand why it wasn't working before (with the inserting in the same method).

Can anyone tell me????


Thanks all,
ltcmelo

p.s.:thanks for your time javamona


Top
 Profile  
 
 Post subject:
PostPosted: Sat May 29, 2004 11:32 am 
Beginner
Beginner

Joined: Mon Sep 29, 2003 10:32 pm
Posts: 35
Location: Toronto, Ontario
You have
(a)a data problem

It will go into the while loop if there are employees in the tables with fk_orgid = 10. Now for you that should only happen if the code in Mark2 that inserts these records runs. Which makes it odd that it enters the loop only when its commented out.
Check that that is the case.
Also put these line just before the last while loop
System.out.println(org10Employees.size());
System.out.println(org10Employees);

But the code just above that does the same thing. If that works, then the last loop should work as well. (Also, why wouldn't you just use that code to get what you want done)


OR
(b) transaction isolation issue
If what you say is true, and the code that inserts prevents you from seeing the data, then remember that in some cases inserting rows into tables could cause you not to see the data in another transaction.
(I don't see transactional code in your post, so somehow I don't think that's the problem).


Later.


Top
 Profile  
 
 Post subject:
PostPosted: Sat May 29, 2004 12:09 pm 
Beginner
Beginner

Joined: Sun May 16, 2004 3:53 pm
Posts: 47
Location: Belo Horizonte, Brazil
Quote:
Which makes it odd that it enters the loop only when its commented out.


No, i'll explain.


THE NON WORKING WAY FOR THE METHOD
In the beginning, here is what i was doinng.
1 - test the whole method without commenting any lines
2 - was not working (didn't enter in the while loop in MARK 2)
3 - erase all data in db
4 - try again -> doesn't work again

THE WORKING WAY FOR THE METHOD
Now (the way it workd), here is what i do
1 - run only the part of the method that inserts data (comment the rest)
2 - run again the method without the inserting part (comment the insert part, wich i called MARK1), with only the "select" stuff
3 - works, i'm happy, but don't understand why

See the reason
I tried what you said not commenting anything (of course, i erased data in db). Here's what i got out
12:59:31,296 INFO [STDOUT] 0
12:59:31,296 INFO [STDOUT] []


Conclusion, this method simply don't work with the whole parts together and i don't know why. As you said, there's no transaction involved, so, my question is still up.


Thanks again,
ltcmelo


Top
 Profile  
 
 Post subject: Transactions
PostPosted: Sat May 29, 2004 1:32 pm 
Beginner
Beginner

Joined: Mon Sep 29, 2003 10:32 pm
Posts: 35
Location: Toronto, Ontario
Could be a transactional issue. Depending on the transaction isolation, you may not be able to see uncommited data in the same transaction. If that method is a session bean method, and it is declared READ_COMMITTED then chances are the method is behaving correctly.

Try adding session.commit() or session.getTransaction().commit() after the insert statements, or refactor into a separate method.


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 30, 2004 9:58 am 
Beginner
Beginner

Joined: Sun May 16, 2004 3:53 pm
Posts: 47
Location: Belo Horizonte, Brazil
That's the only explanation that now (only now) i see!

Regards,
ltcmelo


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