Announcement Announcement Module
Collapse
No announcement yet.
Load vs Get Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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

  • #2
    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.

    Comment


    • #3
      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

      Comment


      • #4
        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

        Comment


        • #5
          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.

          Comment


          • #6
            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.

            Comment

            Working...
            X