Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: loadAll going to Database?

  1. #1
    Join Date
    Sep 2006
    Location
    Greenville, SC
    Posts
    8

    Default loadAll going to Database?

    I'm trying to get up the learning curve on Spring 2.0 and Hibernate 3.0 in Eclipse 3.2 with IBM DB2 version 8. One thing that stumping me at this point is that the HibernateTemplate.loadAll() method is retrieving from the database on every call. As I read the documentation, it's supposed to return the persisted objects, and not go to the database at all.

    Here is the console log that shows up every time I refresh the web page that shows all the persons--it shows that Hibernate is accessing the database each time.

    13:19:25,159 INFO [RequestInterceptor] Intercepted Request for http://158.158.23.32:8090/frameworkT...tContacts.html
    13:19:25,159 INFO [STDOUT] Hibernate: select person0_.PERSON_ID as PERSON1_11_, person0_.FIRST_NAME as FIRST2_11_, person0_.MIDDLE_NAME as MIDDLE3_11_, person0_.LAST_NAME as LAST4_11_ from FRAMEWORK.PERSON person0_

    I've attached the pieces that I think are pertinent to the discussion. Any help would be greatly appreciated.

    <=============== Person.java ================>

    public class Person implements java.io.Serializable {
    private static final long serialVersionUID = 5454961752650084595L;

    private long personId;
    private String firstName;
    private String middleName;
    private String lastName;

    private Set<PersonAddress> personAddresses = new HashSet<PersonAddress>(0);

    public Person() {
    }
    public long getPersonId() {
    return this.personId;
    }
    public void setPersonId(long personId) {
    this.personId = personId;
    }
    public String getFirstName() {
    return this.firstName;
    }
    public void setFirstName(String firstName) {
    this.firstName = firstName;
    }
    public String getMiddleName() {
    return this.middleName;
    }
    public void setMiddleName(String middleName) {
    this.middleName = middleName;
    }
    public String getLastName() {
    return this.lastName;
    }
    public void setLastName(String lastName) {
    this.lastName = lastName;
    }
    public Set<PersonAddress> getPersonAddresses() {
    return this.personAddresses;
    }
    public void setPersonAddresses(Set<PersonAddress> personAddresses) {
    this.personAddresses = personAddresses;
    }
    public String getFullName() {
    return this.firstName + " " + this.middleName + " " + this.lastName;
    }
    }

    <========== Person.hbm.xml ===============>

    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated Jul 27, 2006 11:12:07 AM by Hibernate Tools 3.1.0.beta5 -->
    <hibernate-mapping>
    <class name="edu.bju.frameworkTest.model.Person" table="PERSON" schema="FRAMEWORK">
    <cache usage="read-write" />
    <id name="personId" type="long">
    <column name="PERSON_ID" />
    <generator class="edu.bju.frameworkTest.util.IdGenerator">
    <param name="tableName">PERSON</param>
    <param name="schema">FRAMEWORK</param>
    </generator>
    </id>
    <property name="firstName" type="string">
    <column name="FIRST_NAME" length="15" />
    </property>
    <property name="middleName" type="string">
    <column name="MIDDLE_NAME" length="15" />
    </property>
    <property name="lastName" type="string">
    <column name="LAST_NAME" length="20" />
    </property>
    <set name="personAddresses" inverse="true">
    <cache usage="read-write"/>
    <key>
    <column name="PERSON_ID" not-null="true" />
    </key>
    <one-to-many class="edu.bju.frameworkTest.model.PersonAddress" />
    </set>
    </class>
    </hibernate-mapping>

    <========== PersonDOAHibernate.java ===============>

    public class PersonDAOHibernate extends AbstractHibernateSpringDAO implements PersonDAO {

    public ArrayList<Person> findAll() {
    return new ArrayList<Person>(super.findAll(Person.class));
    }
    public ArrayList<Person> loadAll() {
    return new ArrayList<Person>(getHibernateTemplate().loadAll(P erson.class));
    }
    public ArrayList<Person> findAll(String sortColumn) {
    return new ArrayList<Person>(super.findAll(Person.class, sortColumn));
    }
    public Person findById(long personId) {
    return (Person) super.load(Person.class, personId);
    }
    public void save(Person person) {
    super.saveOrUpdate(person);
    }
    public void delete(Person person) {
    super.delete(person);
    }
    }

    <========== ehcache.xml ===============>

    <ehcache>
    <diskStore path="java.io.tmpdir"/>
    <defaultCache
    maxElementsInMemory="10000"
    eternal="false"
    timeToIdleSeconds="120"
    timeToLiveSeconds="86400"
    overflowToDisk="true"
    diskPersistent="false"
    diskExpiryThreadIntervalSeconds="120"/>

    <cache name="org.hibernate.cache.StandardQueryCache"
    maxElementsInMemory="10000"
    eternal="false"
    timeToLiveSeconds="86400"
    overflowToDisk="false"/>

    </ehcache>

    <========== hibernate.cfg.xml ===============>

    ?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

    <hibernate-configuration>
    <session-factory name="factory">
    <property name="hibernate.connection.username">db2pbd</property>
    <property name="hibernate.connection.password">db2</property>
    <property name="hibernate.connection.url">jdbc:db2://bjuptsrv.bju.edu:50020/BJUPROD</property>
    <property name="hibernate.connection.driver_class">com.ibm.d b2.jcc.DB2Driver</property>
    <property name="hibernate.dialect">org.hibernate.dialect.DB2 Dialect</property>
    <property name="hibernate.show_sql">false</property>
    <property name="hibernate.default_schema">FRAMEWORK</property>
    <mapping resource="edu/bju/frameworkTest/model/mapping/Person.hbm.xml" />
    </session-factory>
    </hibernate-configuration>

    <========== framework-context.xml ===============>

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans SYSTEM "lib/spring-beans.dtd" >
    <beans>
    <bean id="factory" name="sessionFactory" class="org.springframework.orm.hibernate3.LocalSes sionFactoryBean">
    <property name="mappingResources">
    <list>
    <value>edu/bju/frameworkTest/model/mapping/Person.hbm.xml</value>
    </list>
    </property>
    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">org.hibernate.dialect.DB2D ialect</prop>
    <prop key="hibernate.show_sql">true</prop>
    <prop key="format_sql">true</prop>
    <prop key="hibernate.cache.provider_class">org.hibernate .cache.EhCacheProvider</prop>
    <prop key="hibernate.cache.use_second_level_cache">true</prop>
    <prop key="hibernate.cache.use_query_cache">true</prop>
    <prop key="hibernate.transaction.flush_before_completion ">true</prop>
    </props>
    </property>
    <property name="dataSource">
    <ref bean="dataSource" />
    </property><!--
    <property name="jtaTransactionManager">
    <ref bean="jtaTransactionManager"/>
    </property> -->
    </bean>

    <!-- ===================== DAOs ==================== -->
    <bean id="PersonDAOHibernateManaged" parent="txAffirmative">
    <property name="target">
    <bean class="edu.bju.frameworkTest.model.dao.hibernate.P ersonDAOHibernate">
    <property name="sessionFactory" ref="factory" />
    </bean>
    </property>
    </bean>

    <!-- ===================== Security ==================== -->
    <bean id="filterInvocationInterceptor" parent="baseFilterInvocationInterceptor">
    <property name="objectDefinitionSource">
    <value>
    /editContact.html.*=ROLE_FRAMEWORKTEST_MGR
    /.+\.html=ROLE_USER
    /.+\.ajax=ROLE_USER
    /.+\.jsp=ROLE_USER
    /switchUser.jsp.*=ROLE_WEB_DEVELOPER
    /j_acegi_switch_user.*=ROLE_WEB_DEVELOPER
    </value>
    </property>
    </bean>

    </beans>

    <========== framework-servlet.xml ===============>

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans SYSTEM "lib/spring-beans.dtd" >
    <beans>

    <bean id="urlMapping" class="org.springframework.web.servlet.handler.Sim pleUrlHandlerMapping">
    <property name="interceptors">
    <list>
    <ref bean="requestInterceptor" />
    <ref bean="openSessionInView" />
    </list>
    </property>
    <property name="mappings">
    <props>
    <prop key="/listContacts.html">listContactsController</prop>
    <prop key="/editContact.html">editContactController</prop>
    </props>
    </property>
    </bean>

    <bean name="requestInterceptor" class="edu.bju.shared.util.spring.RequestIntercept or" />

    <bean id="openSessionInView" class="org.springframework.orm.hibernate3.support. OpenSessionInViewInterceptor">
    <property name="sessionFactory" ref="factory" />
    <property name="singleSession" value="true" />
    </bean>

    <bean id="listContactsController" class="edu.bju.frameworkTest.controller.ListContac tsController">
    <property name="personDAO">
    <ref bean="PersonDAOHibernateManaged"/>
    </property>
    </bean>

    <bean id="editContactValidator" class="edu.bju.frameworkTest.controller.validator. EditContactValidator" />

    <bean id="editContactController" class="edu.bju.frameworkTest.controller.EditContac tController">
    <property name="personDAO" ref="PersonDAOHibernateManaged" />
    <property name="sessionForm" value="true" />
    <property name="commandName" value="editContactWrapper" />
    <property name="commandClass" value="edu.bju.frameworkTest.controller.wrapper.Ed itContactWrapper" />
    <property name="validator" ref="editContactValidator" />
    <property name="formView" value="editContacts" />
    <property name="successView" value="listContacts.html" />
    </bean>

    </beans>

  2. #2
    Join Date
    Jul 2006
    Location
    Philadelphia, PA, USA
    Posts
    341

    Default Clarification

    Hi ccollins_29687,

    Quote Originally Posted by ccollins_29687
    One thing that stumping me at this point is that the HibernateTemplate.loadAll() method is retrieving from the database on every call. As I read the documentation, it's supposed to return the persisted objects, and not go to the database at all.
    I don't really understand what you mean. Are you wondering why the database is being accessed even though you have the second level cache enabled? Because I don't think anything about the HibernateTemplate.loadAll documentation makes it seem that the database is not being accessed.

    -Arthur Loder

  3. #3
    Join Date
    Sep 2006
    Location
    Greenville, SC
    Posts
    8

    Default

    Maybe I'm misunderstanding the JavaDocs on the Spring site. According to the JavaDocs, the HibernateTemplate.loadAll method does the following:

    Return all persistent instances of the given entity class.

    That sounds like the same as "return what's in the cache without re-querying the database" to me. Apparently that's not what it means.

    If that method is supposed to go to the DB, is there a method that just gives me what is loaded into cache and doesn't go back to the DB? I could use createQuery("from Person").setCacheable(true), but that also reloads from the DB anytime an object in the cache changes. Once the objects are initially loaded, the objects are supposed cached in memory--including the changes that have been made in the app and saved to the DB, so I'm assuming there has to be a way to get them from cache. Assuming there are no outside influences on the DB, what I have in cache should always be authoritative.

    Am I missing something? Isn't the whole point of caching to get it once from the database and then always from memory after that?

  4. #4
    Join Date
    Jul 2006
    Location
    Philadelphia, PA, USA
    Posts
    341

    Default

    Quote Originally Posted by ccollins_29687
    Return all persistent instances of the given entity class.

    That sounds like the same as "return what's in the cache without re-querying the database" to me. Apparently that's not what it means.
    I read the API as "return all persistent instances; if I have enabled the second level cache and the cache contains the instances, return the instances from the cache; otherwise, access the database."

    I have never worked with Hibernate's caching support before, but I don't think there are cache-specific methods. If there were, that would mean you would have to change application code if you change/add/remove caching. I think application code is unaware of the cache (except some methods like SessionFactory.evict). I'm sure someone with more Hibernate knowledge would be able to explain better.

    That being said, I don't understand why your setup does not result in persistent objects being returned from the second level cache...

    -Arthur Loder

  5. #5
    Join Date
    Oct 2004
    Location
    Herndon, VA, US
    Posts
    648

    Default

    Try getHibernateTemplate().setCacheQueries() before calling loadAll() on the same template instance.

    I agree with Arthur. I don't think there is anything in Hibernate that lets us go "look, I know it's in the cache, so don't go to the database, ever."
    --Jing Xue

  6. #6
    Join Date
    Sep 2006
    Location
    Greenville, SC
    Posts
    8

    Default

    Quote Originally Posted by manifoldronin
    I agree with Arthur. I don't think there is anything in Hibernate that lets us go "look, I know it's in the cache, so don't go to the database, ever."
    Please bear with a junior-level Java developer trying to understand how Hibernate fits into the overall picture.

    Perhaps the problem is in my understanding or expectations. Hibernate is a persistence framework, which means it manages the caching for me. But if I can't control when it goes to the DB and when it returns just the cache, then isn't it's usefulness limited? I must be missing something, because I'm thinking the whole reason for persistence is to avoid unnecessary DB calls, and it sounds like we're saying here that Hibernate can't necessarily be made to do that.

    There are (at least) two reasons I want caching. In one case, I want to cache objects that I am using regularly that are somewhat dynamic, that may or may not change within the app, but that I don't want to reload if I can help it. These typically map to database tables. There has to be some DB interaction, but it should be limited and intelligent, and largely under my control. If the data for a record was changed in my app, and if I'm using Hibernate to manage the objects and their persistence, then I'm not sure why Hibernate would need to refresh that object from the DB ever. It should write changes to the DB, but the object in memory remains authoritative, so a refresh from the DB shouldn't be necessary.

    A second use of caching that I expect to use is to store the results of a large Select that is completely static, where my goal is to load it once and then use the cache for all operations. This type of Select would typically involve a join of several tables and return a few thousand rows. In this case, I know this data is static and there is no reason to go back to the DB. And having HQL available to query that static cache would be great, if I can tell Hibernate that one load is all it needs. If I can't tell Hibernate to load it once and then return the cache forever after, then I must have a wrong understanding of what a persistence framework is and does.

    I still need to figure out why Hibernate isn't returning the objects from my second-level cache (EHCache), but I also need to verify that my expectations of Hibernate are realistic.

  7. #7
    Join Date
    Sep 2006
    Location
    Greenville, SC
    Posts
    8

    Default

    Quote Originally Posted by manifoldronin
    Try getHibernateTemplate().setCacheQueries() before calling loadAll() on the same template instance.
    I appreciate the suggestion. However, it's still reloading the entire data set whenever I issue a SaveOrUpdate. This appears to be the same functionality as getHibernateTemplate().createQuery("from Person").setCacheable(true). If one object in the data set changes, it reloads the entire data set, even though it already had the updated object.

  8. #8
    Join Date
    Jul 2006
    Location
    Philadelphia, PA, USA
    Posts
    341

    Default HibernateTemplate.setCacheQueries

    The HibernateTemplate.setCacheQueries method deals with Hibernate's Query and Criteria cache (not the second-level cache). Here is an excerpt from this site about Hibernate's Query cache:

    Note that the query cache does not cache the state of the actual entities in the result set; it caches only identifier values and results of value type. So the query cache should always be used in conjunction with the second-level cache.

    So you still need to use Hibernate's second-level cache to achieve what you want.

    -Arthur Loder

  9. #9
    Join Date
    Jul 2006
    Location
    Philadelphia, PA, USA
    Posts
    341

    Default Persistence = caching?

    Quote Originally Posted by ccollins_29687
    Hibernate is a persistence framework, which means it manages the caching for me. But if I can't control when it goes to the DB and when it returns just the cache, then isn't it's usefulness limited? I must be missing something, because I'm thinking the whole reason for persistence is to avoid unnecessary DB calls, and it sounds like we're saying here that Hibernate can't necessarily be made to do that.
    In reference to the above quote, I have to say I disagree. I have enjoyed using Hibernate for some time without ever dealing with its caching. Persistence and caching are two separate (but related) issues. Hibernate can help in both areas, but it would be incorrect to say that a non-caching Hibernate solution is useless.

    I can, however, understand your frustration. I have not worked with Hibernate's caching facilities, so I can't really help you. Most likely, this is a Hibernate issue and has nothing to do with Spring, so you might want to also try one of their forums.

    Sorry I can't be of more helps!

    -Arthur Loder

  10. #10
    Join Date
    Sep 2006
    Location
    Greenville, SC
    Posts
    8

    Default

    Quote Originally Posted by Arthur Loder
    In reference to the above quote, I have to say I disagree. I have enjoyed using Hibernate for some time without ever dealing with its caching. Persistence and caching are two separate (but related) issues. Hibernate can help in both areas, but it would be incorrect to say that a non-caching Hibernate solution is useless.
    -Arthur Loder
    I must misunderstand "persistence" then, because I thought persistence and caching were synonmous. If persistence doesn't mean to persist objects in memory (caching them), then what does it mean?

    I overstated my case when I implied that Hibernate was useless without caching--I do understand that the mapping of DB tables and columns to Java objects is a very helpful feature. But right now my sights are honed in on caching, and I'm trying to determine whether Hibernate can be made to do what we need or not.

Posting Permissions

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