Results 1 to 7 of 7

Thread: Hibernate returns null for Integer properties

Hybrid View

  1. #1
    Join Date
    Apr 2005
    Posts
    19

    Default 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. #2
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    post the mappings and the relevant piece of code.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  3. #3
    Join Date
    Apr 2005
    Posts
    19

    Default

    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

  4. #4
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    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.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

  5. #5
    Join Date
    Apr 2005
    Posts
    19

    Default

    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

  6. #6
    Join Date
    Sep 2004
    Posts
    1,086

    Default

    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.

  7. #7
    Join Date
    Apr 2005
    Posts
    19

    Default

    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

Similar Threads

  1. Hibernate Long Session Per Flow?
    By akw in forum Web Flow
    Replies: 21
    Last Post: Dec 12th, 2005, 08:06 PM
  2. Replies: 2
    Last Post: Oct 17th, 2005, 08:41 PM
  3. Replies: 4
    Last Post: Sep 27th, 2005, 11:31 PM
  4. Replies: 3
    Last Post: May 16th, 2005, 07:04 AM
  5. Strange Data Access Error
    By webifyit in forum Data
    Replies: 2
    Last Post: Dec 28th, 2004, 11:06 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •