2 Replies Latest reply on Feb 19, 2007 7:47 PM by mikedougherty

    OneToMany does not load

    mikedougherty

      I have a couple Entities that have @OneToMany relationships with each other. I define them as so..

      @Entity
      public class District implements Serializable {
      
       private Long id;
       private String name;
       private Region region;
       private Manager manager;
       @DataModel
       private List<Store> stores;
      
       @Id @GeneratedValue
       public Long getId() {
       return id;
       }
      
       public void setId(Long id) {
       this.id = id;
       }
      
       @Length(max=150)
       public String getName() {
       return name;
       }
      
       public void setName(String name) {
       this.name = name;
       }
      
       @ManyToOne @JoinColumn(name="region_id", nullable=false)
       public Region getRegion() {
       return region;
       }
      
       public void setRegion(Region region) {
       this.region = region;
       }
      
       @OneToOne @JoinColumn(name="manager_id", nullable=false)
       public Manager getManager() {
       return manager;
       }
      
       public void setManager(Manager manager) {
       this.manager = manager;
       }
      
       @OneToMany(cascade=ALL, mappedBy="id", fetch=EAGER)
       public List<Store> getStores() {
       return stores;
       }
      
       public void setStores(List<Store> stores) {
       this.stores = stores;
       }
      
      }
      


      @Entity
      public class Store implements Serializable {
      
       private Long id;
       private String name;
       private String street;
       private String city;
       private String state;
       private String postalCode;
       private District district;
      
       @Id @GeneratedValue
       public Long getId() {
       return id;
       }
      
       public void setId(Long id) {
       this.id = id;
       }
      
       @Length(max=20)
       public String getName() {
       return name;
       }
      
       public void setName(String name) {
       this.name = name;
       }
      
       public String getCity() {
       return city;
       }
      
       public void setCity(String city) {
       this.city = city;
       }
      
       @Column(name="postal_code")
       public String getPostalCode() {
       return postalCode;
       }
      
       public void setPostalCode(String postalCode) {
       this.postalCode = postalCode;
       }
      
       public String getState() {
       return state;
       }
      
       public void setState(String state) {
       this.state = state;
       }
      
       public String getStreet() {
       return street;
       }
      
       public void setStreet(String street) {
       this.street = street;
       }
      
       @ManyToOne(optional=false, fetch=EAGER)
       @JoinColumn(name="district_id", nullable=false)
       public District getDistrict() {
       return district;
       }
      
       public void setDistrict(District district) {
       this.district = district;
       }
      }
      


      The relationship definition seems to work fine because when I create a Store it maintains the proper District relationship in the database.

      mysql> select * from District;
      +----+-----------+-----------+------------+
      | id | name | region_id | manager_id |
      +----+-----------+-----------+------------+
      | 1 | district1 | 1 | 1 |
      +----+-----------+-----------+------------+
      


      mysql> select * from Store;
      +----+--------+---------------+------+-------+-------------+-------------+
      | id | name | street | city | state | postal_code | district_id |
      +----+--------+---------------+------+-------+-------------+-------------+
      | 1 | store1 | 123 my street | city | st | 12345 | 1 |
      | 2 | store2 | 456 my street | city | st | 12345 | 1 |
      +----+--------+---------------+------+-------+-------------+-------------+
      


      However, when I try to load this District I am getting very odd behavior. With the @GeneratedValue annotations (as above) the following DataTable only shows Store "store1".

       <h:dataTable var="store"
       value="#{districtHome.instance.stores}"
       rendered="#{ not empty districtHome.instance.stores }"
       id="stores">
       <h:column>
       <f:facet name="header">Name</f:facet>
       <h:outputText value="#{store.name}"/>
       </h:column>
       </h:dataTable>
      


      In reality I do not want @GeneratedValue's for the Id field. But when I remove the @GeneratedValue annotation and input the Id's via the form I get no results in the <h:dataTable /> at all.

      Nothing I have tried seems to be getting me anywhere. I've tried using that dataTable and not. I've tried using Set's and List's. I've tried it with the following in the DistrictHome.java:

       public List<Store> getStores() {
       return getInstance() == null ||
       getInstance().getStores() == null ? null :
       new ArrayList<Store>(getInstance().getStores());
       }
      


      And...

       <h:dataTable var="store"
       value="#{districtHome.stores}"
       rendered="#{ not empty districtHome.stores }"
       id="stores">
       <h:column>
       <f:facet name="header">Name</f:facet>
       <h:outputText value="#{store.name}"/>
       </h:column>
       </h:dataTable>
      
      


      All of which either give me no items in the stores Collection, or only one (when I expect two). I've gone through the examples (which is where I got the DistrictHome idea) and can not seem to find any differences (that solve the problem) between my code and the example code. I am at a complete loss at this point.

      Where or how can I debug this to find out what the problem is and fix it? Any thoughts at all on what might be causing the problem?

      Thanks.

        • 1. Re: OneToMany does not load
          pmuir

          Put a break point on the District.getStores() method and see what the stores variable contains. If it has only one store then the problem is hibernate related (so ask there as you'll get more help), otherwise come back here. Make sure you are working with an uptodate version of the entity.

          • 2. Re: OneToMany does not load
            mikedougherty

            Thanks for the reply petemuir. I sort of expected it to be a Hibernate issue. But I am unclear as to where Seam leaves off and Hibernate takes over, so I figured I'd start here.

            The "show sql" Hibernate option is on in seam-gen projects by defaut, but I need to look at the SQL a little closer next time. After looking though the SQL, I realized that

             @OneToMany(cascade=ALL, mappedBy="id", fetch=EAGER)
             public List<Store> getStores() {
             return stores;
             }
            


            Should have actually been...

             @OneToMany(cascade=ALL, mappedBy="district", fetch=EAGER)
             public List<Store> getStores() {
             return stores;
             }
            


            The "mappedBy" attribute should point to the property in the Store object which will contain the mapped District object.

            Anyway, thanks again for the response.