Announcement Announcement Module
Collapse
No announcement yet.
Hibernate returns null for Integer properties Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Hibernate returns null for Integer properties

    Hi all,

    I have a situation where model classes contain a list of related model classes etc. 2 and more levels deap. When I load a top level model object it's attributes are correctly populated, but when I call getXXX() to retrieve Integer attributes from contained objects, or further down the tree, I get null.

    All are relationships are:

    Code:
    hibernate.many-to-one
    update="false" insert="false"
    not-null="true" cascade="none" lazy="true"
    I've tried switching lazy to false but it does not solve the problem.

    I'm using Hibernate 3.0 inside Spring 1.2 rc1 and perform load operations through the HibernateTemplate.get(clazz, key).

    Any ideas how to fix this problem. Thanks,
    Stefan

  • #2
    post the mappings and the relevant piece of code.

    Comment


    • #3
      Hi Costin,

      The Handler code in the Controller layer:

      Code:
      	public ModelAndView selectTablesHandler (
      	        HttpServletRequest request, HttpServletResponse response)
      	throws ServletException {
      	    
      	    ModelAndView mav = null;
      	    try {
      	        int[] databases = RequestUtils.getIntParameters(request, "databaseIds");
      			request.getSession().setAttribute(WebConstants.SESSION_SELECTED_DATABASES, databases);
      	        List displayTables = new ArrayList();
                  List tables = new ArrayList();
      	        for &#40;int i = 0; i < databases.length; i++&#41; &#123;
      	            Database database = service.loadDatabase&#40;new Integer&#40;databases&#91;i&#93;&#41;&#41;;
      	            tables = new ArrayList&#40;&#41;;
      	            tables.addAll&#40;service.loadAllTablesForDatabase&#40;new Integer&#40;databases&#91;i&#93;&#41;&#41;&#41;;
      	            for &#40;Iterator iter = tables.iterator&#40;&#41;; iter.hasNext&#40;&#41;;&#41; &#123;
                          Table table = &#40;Table&#41; iter.next&#40;&#41;;
      	                LabelValue tableLabel = new LabelValue&#40;&#41;;
      	                tableLabel.setLabel&#40;new String&#40;database.getName&#40;&#41;&#41;+"."+table.getName&#40;&#41;&#41;;
      
      // ****** This is the line that returns a null &#40;actually -1 when it detects null&#41;
      	                tableLabel.setValue&#40;new String&#40;database.getId&#40;&#41;+","+table.getId&#40;&#41;&#41;&#41;;
      
      	                tableLabel.setSelected&#40;Boolean.TRUE&#41;;
      		            displayTables.add&#40;tableLabel&#41;;
      	            &#125;
      	        &#125;
      	        mav = new ModelAndView&#40;"selectTablesForActivationView", 
      	                "tables", displayTables&#41;;
      	    &#125; catch &#40;ObjectNotFoundException e&#41; &#123;
      	        if &#40;logger.isErrorEnabled&#40;&#41;&#41; &#123;
      	            logger.error&#40;e.getMessage&#40;&#41;, e&#41;;
      	        &#125;
      	        throw new ServletException&#40;e.getMessage&#40;&#41;, e&#41;;
      	    &#125;
      .
      .
      .
      The code from the service layer:
      Code:
          public List loadAllTableMappers&#40;&#41; throws LoadObjectsFailedException &#123;
      		List result = new ArrayList&#40;&#41;;
      		try &#123;
      
      // ****** 
      			result = this.getDao&#40;&#41;.getObjects&#40;TableMapper.class&#41;;
      
      		&#125; catch &#40;ObjectRetrievalFailureException e&#41; &#123;
      			throw new LoadObjectsFailedException&#40;e.getMessage&#40;&#41;, e&#41;;
      		&#125;
      		return result;
          &#125;
      And from the DAO:
      Code:
      	public List getObjects&#40;Class clazz&#41; &#123;
      
      // ****** 
      		return getHibernateTemplate&#40;&#41;.loadAll&#40;clazz&#41;;
      	&#125;
      Database model class:
      Code:
      public class Database extends AbstractModelObject implements Serializable &#123;
      
      	private Integer id;
      
      	private String name;
      
      	private String dbmsServerName;
      
      	private String dbmsServerConnect;
      
      	private Dbms dbms = new Dbms&#40;&#41;;
      
      // ****** 
      	private List tablesInDatabase = new ArrayList&#40;&#41;;
      	
      	private Integer version;
      
      .
      .
      .
      TablesInDatabase model class:

      Code:
      public class TableInDatabase extends AbstractModelObject &#123;
      
      	private TableInDatabaseId compositeId;
      
      	private Database database = new Database&#40;&#41;;
      
      // ****** 
      	private Table table = new Table&#40;&#41;;
      
      	private String insertConflictFlag;
      .
      .
      .
      Table model class:

      Code:
      public class Table extends AbstractModelObject &#123;
      	
      // ****** 
      	private Integer id;
      	
      	private String name;
      
      	private String schema;
      
      	private List columns = new ArrayList&#40;&#41;;
      
      	private List primaryKeyColumns = new ArrayList&#40;&#41;;
      
      	private Boolean hasFloats;
      
      	private List databases = new ArrayList&#40;&#41;;
      	
      	private Integer version;
      .
      .
      .
      	/**
      	 * Returns the unique identifier for this Database.
      	 * @return Returns the id.
      	 * @hibernate.id generator-class="native" column="TableId"
      	 *               unsaved-value="-1"
      	 */
      	public final int getId&#40;&#41; &#123;
      
      // ****** 
      // if ID is null, return -1
      		return &#40;id == null ? -1 &#58; id.intValue&#40;&#41;&#41;;
      	&#125;
      
      	/**
      	 * Set a new unique identifier for this database.
      	 * @param id The id to set.
      	 */
      	public final void setId&#40;int id&#41; &#123;
      		this.id = new Integer&#40;id&#41;;
      	&#125;
      .
      .
      .
      Hibernate mapping file for Database:
      Code:
      <hibernate-mapping
      >
          <class
              name="za.co.telkom.ubr.model.Database"
              table="ReplDatabases"
          >
      
              <id
                  name="id"
                  column="DatabaseId"
                  type="int"
                  unsaved-value="-1"
              >
                  <generator class="native">
                    <!--  
                        To add non XDoclet generator parameters, create a file named 
                        hibernate-generator-params-Database.xml 
                        containing the additional parameters and place it in your merge dir. 
                    --> 
                  </generator>
              </id>
      
              <version
                  name="version"
                  column="version"
                  type="java.lang.Integer"
              />
      
              <property
                  name="name"
                  type="java.lang.String"
                  update="true"
                  insert="true"
                  column="DatabaseName"
                  length="64"
                  not-null="true"
              />
      
              <property
                  name="dbmsServerName"
                  type="java.lang.String"
                  update="true"
                  insert="true"
                  column="DBMSServerName"
                  length="64"
                  not-null="true"
              />
      
              <property
                  name="dbmsServerConnect"
                  type="java.lang.String"
                  update="true"
                  insert="true"
                  column="DBMSServerConnect"
                  length="255"
                  not-null="true"
              />
      
              <many-to-one
                  name="dbms"
                  class="za.co.telkom.ubr.model.Dbms"
                  cascade="none"
                  outer-join="auto"
                  update="true"
                  insert="true"
                  column="DBMSId"
                  not-null="true"
              />
      
              <bag
                  name="tables"
                  lazy="false"
                  inverse="true"
                  cascade="all"
                  order-by="TableId"
              >
      
                  <key
                      column="DatabaseId"
                  >
                  </key>
      
                  <one-to-many
                        class="za.co.telkom.ubr.model.TableInDatabase"
                  />
      
            </bag>
      
              <!--
                  To add non XDoclet property mappings, create a file named
                      hibernate-properties-Database.xml
                  containing the additional properties and place it in your merge dir.
              -->
      
          </class>
      
      </hibernate-mapping>
      Hibernate mapping file for TablesInDatabase:
      Code:
      <hibernate-mapping
      >
          <class
              name="za.co.telkom.ubr.model.TableInDatabase"
              table="ReplTableInDatabase"
          >
      
              <composite-id
                  name="compositeId"
                  class="za.co.telkom.ubr.model.TableInDatabaseId"
              >
                           <key-property
                              name="databaseId"
                              type="java.lang.Integer"
                              column="DatabaseId"
                      />
      
                           <key-property
                              name="tableId"
                              type="java.lang.Integer"
                              column="TableId"
                      />
      
              </composite-id>
      
              <many-to-one
                  name="database"
                  class="za.co.telkom.ubr.model.Database"
                  cascade="none"
                  outer-join="auto"
                  update="false"
                  insert="false"
                  column="DatabaseId"
                  not-null="true"
              />
      
              <many-to-one
                  name="table"
                  class="za.co.telkom.ubr.model.Table"
                  cascade="none"
                  outer-join="auto"
                  update="false"
                  insert="false"
                  column="TableId"
                  not-null="true"
              />
      
              <property
                  name="insertConflictFlag"
                  type="java.lang.String"
                  update="true"
                  insert="true"
                  column="InsertConflictFlag"
                  length="1"
                  not-null="true"
              />
      
              <!--
                  To add non XDoclet property mappings, create a file named
                      hibernate-properties-TableInDatabase.xml
                  containing the additional properties and place it in your merge dir.
              -->
      
          </class>
      
      </hibernate-mapping>
      Hibernate mapping file for Table:
      Code:
      <hibernate-mapping
      >
          <class
              name="za.co.telkom.ubr.model.Table"
              table="ReplTables"
          >
      
              <id
                  name="id"
                  column="TableId"
                  type="int"
                  unsaved-value="-1"
              >
                  <generator class="native">
                    <!--  
                        To add non XDoclet generator parameters, create a file named 
                        hibernate-generator-params-Table.xml 
                        containing the additional parameters and place it in your merge dir. 
                    --> 
                  </generator>
              </id>
      
              <property
                  name="name"
                  type="java.lang.String"
                  update="true"
                  insert="true"
                  column="TableName"
                  length="64"
                  not-null="true"
              />
      
              <property
                  name="schema"
                  type="java.lang.String"
                  update="true"
                  insert="true"
                  column="SchemaName"
                  length="64"
                  not-null="true"
              />
      
              <bag
                  name="columns"
                  lazy="true"
                  inverse="true"
                  cascade="all"
                  order-by="Sequence"
              >
      
                  <key
                      column="TableId"
                  >
                  </key>
      
                  <one-to-many
                        class="za.co.telkom.ubr.model.Column"
                  />
      
            </bag>
      
              <property
                  name="hasFloats"
                  type="boolean"
                  update="true"
                  insert="true"
                  column="HasFloatColumns"
                  not-null="true"
              />
      
              <bag
                  name="databases"
                  lazy="true"
                  inverse="true"
                  cascade="all"
                  order-by="DatabaseId"
              >
      
                  <key
                      column="TableId"
                  >
                  </key>
      
                  <one-to-many
                        class="za.co.telkom.ubr.model.TableInDatabase"
                  />
      
            </bag>
      
              <property
                  name="version"
                  type="java.lang.Integer"
                  update="true"
                  insert="true"
                  column="Version"
                  not-null="true"
              />
      
              <!--
                  To add non XDoclet property mappings, create a file named
                      hibernate-properties-Table.xml
                  containing the additional properties and place it in your merge dir.
              -->
      
          </class>
      
      </hibernate-mapping>
      Regards,
      Stefan

      Comment


      • #4
        Make the fields protected from private - you are extending the AbstractModelObject and the composite key is not going to be seen in the subclass and thus HB will not be aware of it.

        Comment


        • #5
          Hi Costin,

          I've made all attributes in my model classes and composite ID classes protected, but it does not solve the problem. Note that the common AbstractModelObject does not declare any attributes, only equals(), toString() and hashcode() methods.

          Any further suggestions?

          Thanks for your help.

          Regards,
          Stefan

          Comment


          • #6
            I think you should use key-many-to-one and not key-property and many-to-one for the same columns. It may be it has nothing to do with your problem but it's worth a try.

            Other then that - you didn't post your composite key class.

            Comment


            • #7
              Thanks dejanp, but key-many-to-one does not work.

              The composite is so simple that I did not post it, but here it is:

              Code:
              public class TableInDatabaseId implements Serializable &#123;
              
                  protected Integer databaseId;
              
                  protected Integer tableId;
              .
              .
              .
              I have traced the problem right down to the

              Code:
              getHibernateTemplate&#40;&#41;.find&#40;
                              "from TableInDatabase d where d.database.id=?", databaseId&#41;;
              statement in the DAO so it has to be either my mapping, the Spring getHibernateTemplate().find(...) or Hibernate itself.

              Regards,
              Stefan

              Comment

              Working...
              X