Results 1 to 5 of 5

Thread: Hibernate: load() has no session, get() does! Why is that?

  1. #1

    Default Hibernate: load() has no session, get() does! Why is that?

    Hy everybody,
    I'm trying to load a pojo from a database. It gets persisted fine, but then, when I try to load() it I get a Exception saying:

    Code:
    org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    This wouldn't be very surprising on itself. But when I use session.get() instead of session.load() I get the correct entity - no exceptions at all. This is very strange to me. I'm posting my code below. I'm using maven to manage my libs, I am using hibernate 3.2.5ga hibernate annotations 3.3.0ga and spring 2.0.7. Are there known dependency mismatches on these versions?

    The log output:
    Code:
    03:49:47,243  INFO HibernateTransactionManager:383 - Using DataSource [org.springframework.jdbc.datasource.DriverManagerDataSource@89dd] of Hibernate SessionFactory for HibernateTransactionManager
    Hibernate: insert into TestEntity (testProperty) values (?)
    03:49:47,394 ERROR LazyInitializationException:19 - could not initialize proxy - no Session
    org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    	at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
    	at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
    	at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
    	at com.hibernatetest.TestEntity$$EnhancerByCGLIB$$210cad81.getTestProperty(<generated>)
    	at com.hibernatetest.Test.main(Test.java:25)

    My pojo class:
    Code:
    @Entity
    public class TestEntity implements Serializable {
    	private static final long serialVersionUID = 8140827016289126995L;
    	private Long id;
    	private String testProperty;
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	public Long getId() {
    		return id;
    	}
    	public void setId(Long id) {
    		this.id = id;
    	}
    	public String getTestProperty() {
    		return testProperty;
    	}
    
    	public void setTestProperty(String testProperty) {
    		this.testProperty = testProperty;
    	}
    	@Override
    	public boolean equals(Object obj) {
    		return EqualsBuilder.reflectionEquals(this, obj);
    	}
    	@Override
    	public int hashCode() {
    		return HashCodeBuilder.reflectionHashCode(this);
    	}
    }
    My test class:

    Code:
    	public static void main(String[] args) {
        	try{
        		FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext("conf/applicationContext.xml");
        		TestEntityManager manager = (TestEntityManager) ctx.getBean("testEntityManager");
    	    	TestEntity entity = new TestEntity();
    	    	entity.setTestProperty("Hello World");
    	    	Long id = manager.save(entity);
        		TestEntity dbEntity = manager.findById(id);
        		System.out.println(dbEntity.getTestProperty());
        	}catch(Throwable e){
        		e.printStackTrace();
        	}
    	}
    The DAO to which the call is relayed by way of the manager class. This is the class where the load() call occurs. If I just change the call to get() everything is fine.
    Code:
    public class TestEntityDAOHibernate extends HibernateDaoSupport implements TestEntityDAO{
    	public Long save(TestEntity entity) {
    		return (Long) getHibernateTemplate().save(entity);
    	}
    	public TestEntity findById(Long id) {
    		return (TestEntity) getHibernateTemplate().load(TestEntity.class, id);
    	}
    }
    my applicationContext.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
    
    	<bean id="propertyConfigurer"
    		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    		<property name="location" value="conf/jdbc.properties" />
    	</bean>
    
    	<!-- Hibernate -->
    	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    		<property name="driverClassName" value="${jdbc.driverClassName}" />
    		<property name="url" value="${jdbc.url}" />
    		<property name="username" value="${jdbc.username}" />
    		<property name="password" value="${jdbc.password}" />
    	</bean>
    
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    		<property name="configurationClass">
    			<value>org.hibernate.cfg.AnnotationConfiguration</value>
    		</property>
    		<property name="configLocation" value="conf/hibernate.cfg.xml" />
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
    				<prop key="hibernate.show_sql">true</prop>
    				<prop key="hibernate.hbm2ddl.auto">update</prop>
    			</props>
    		</property>
    	</bean>
    
    	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory" ref="sessionFactory" />
    	</bean>
    
    	<bean id="testEntityDAO" class="com.hibernatetest.dao.impl.TestEntityDAOHibernate">
    		<property name="sessionFactory" ref="sessionFactory" />
    	</bean>
    	
    	<bean id="testEntityManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="target">
    			<ref bean="testEntityManagerTarget"/>
    		</property>
    		<property name="transactionAttributes">
    			<props>
    				<prop key="*">PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT</prop>
    			</props>
    		</property>
    		<property name="transactionManager">
    			<ref bean="transactionManager"/>
    		</property>
    	</bean>
    
    	<bean id="testEntityManagerTarget" class="com.hibernatetest.service.impl.TestEntityManagerImpl" autowire="byName"/>
    </beans>
    Any ideas what's going wrong here? Is it just a bug in spring or in hibernate?
    Last edited by tag; Nov 15th, 2007 at 09:05 PM.

  2. #2
    Join Date
    Aug 2004
    Location
    San Francisco
    Posts
    423

    Default

    Hi,

    no, it's not a bug, it's the difference in the semantics between get and load. The get method actually populates the object, whereas load creates a proxy to it and then attempts to load the values when you access them. If you still has a transaction/session open when you accessed the property it would load them at that point, but since you don't the exception occurs.

    Look at the Hibernate docs for more info on the difference between load and get.

    Jonny

  3. #3

    Default

    Wow, I was so used to using OpenSessionInView in a web environment that I forgot about it completely. Anyways, that would mean I'd open a session every time I access my dao. Even worse - Lazy loading wouldn't work at all, unless I open a session everytime I access a getter. Is there some kind of pattern I can use to coordinate this?

  4. #4
    Join Date
    Jul 2005
    Posts
    10

    Default

    If you are using a service layer you can still do something similar to the OpenSessionInView pattern. Just have the entry of a service open and session and keep it open until the end of the service call. Pretty common in the spring world.

  5. #5

    Default

    Okay, for now I think I'll keep to using HibernateInterceptor. When I move my modules into the service environment I'll change that pattern. Thank y'all

Posting Permissions

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