Results 1 to 6 of 6

Thread: Load vs Get

  1. #1
    Join Date
    Dec 2004
    Location
    CA
    Posts
    208

    Default Load vs Get

    Greetings! (Sorry title is misleading. I mean load from dao vs hibernateTemplate.load)

    I am running a unit test comparing my dao loading of an object and an object loaded directly using hibernate template. The same style of testing, found in the petclinic example, except that I am using a "hibernateTemplate" instead of "jdbcTemplate".

    When I run the following function, it fails; indicating to me that two different objects were loaded. Don't understand why this is the case, since I am loading the same object within the same session.

    Code:
    
    
    
    public void testloadCatalog () {
    
    Catalog catalog = catalogDao.loadCatalog(TEST_CATALOG); assertEquals("HQL query must get the same persistent Catalog object", hibernateTemplate.load(Catalog.class, TEST_CATALOG), catalog);
    }

    Curtney
    Curtney Jacobs

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

    Default

    You can check the sources and the Hibernate documentation on load. In short, load doesn't retrieve the actual object but creates a proxy which will be initialized once you actually get to use it. I assume your test fails since the two objects are not actually initilialized and the equals() methods of the proxy is used which most likely is implemented as a simple instance equality.
    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
    Dec 2005
    Posts
    8

    Default Use Hibernate.initialize()

    Other option is to use Hibernate.initialize() to initialise the object, however, it requires the Hibernate session to still be active. If you run your test method with a transaction template + transaction callback and move all your code into the callback then this will work.

    Checkout 19.1.4 of:
    http://www.hibernate.org/hib_docs/v3...rformance.html

  4. #4
    Join Date
    Dec 2004
    Location
    CA
    Posts
    208

    Default

    I assume your test fails since the two objects are not actually initilialized and the equals() methods of the proxy is used which most likely is implemented as a simple instance equality.
    Costin, since hibernate uses a subclass of the class ("...By default, Hibernate uses a subclass of the class...") for the proxy, wouldn't the equal and hashCode method be used? I have implemented equals and hashCode for all my persistent classes. For example, the class in question is implemented as follows:

    Code:
    public boolean equals(Object object) {
    		if (object == this) {
    			return true;
    		}
    		if (!(object instanceof Catalog)) {
    			return false;
    		}
    		Catalog rhs = (Catalog) object;
    		return new EqualsBuilder().append(this.name, rhs.name).isEquals();
    	}
    
    public int hashCode() {
    		return new HashCodeBuilder(-665660147, -839708235)
    			.append(this.name).toHashCode();
    	}

    Beel, thanks for the alternative.

    _
    Curtney
    Curtney Jacobs

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

    Default

    No, not really. You might want to use your object properties (like id) or not - either way the proxy can't distinguish if your methods use them or not. And since the object is not initialize the real method can't be called. However, java requires equals() to be implemented and thus the proxy needs to return a proper equals() and hashcode().
    Do a simple test - see what hashCode the objects and if they are equal before and after you initialize them with Hibernate.initialize().
    Also an alternative is to use find which will always return an actual object and not a proxy.
    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

  6. #6
    Join Date
    Dec 2005
    Posts
    8

    Default Use getter not instance variable

    Your error is caused by the fact you're using this.name. When hibernate generates a proxy subclass using CGlib it'll also shadow all the instance variables. Hence are always null. You equals method should be instead:

    return new EqualsBuilder().append(getName(), rhs.getName()).isEquals();

    Similarly when generating the hashcode you should use getters. Probably safer anyway. Hibernate can only know that it needs to lazy load something if you invoke a getter.

Posting Permissions

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