Announcement Announcement Module
Collapse
No announcement yet.
Lazy relationship initialization in service layer Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Lazy relationship initialization in service layer

    I have a JPA entity with a OneToMany relationship lazy loaded.
    I use Sping Data JPA to retrieve the entity, and in a method of my service I need to retrieve that list initialized, 'cause I need to print it in a JSP. What I've done is:

    Code:
    @Override
    @Transactional(readOnly=true, propagation=Propagation.REQUIRED)
    public User retrieveUser(String username) {
        final User user = userRepository.findByUsername(username);
        user.getFriends().size(); //This line throws a LazyInitializationException
        return user;
    }
    But this solution doesn't work nor is elegant, how can I achieve it?

    The exception is:

    Code:
    org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: it.nikeconsulting.chirp.domain.User.follows, no session or session was closed
    	at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:489)
    	at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:447)
    	at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:139)
    	at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:242)
    	at it.nikeconsulting.chirp.domain.service.ChirpUserServiceImpl.retrieveUser(ChirpUserServiceImpl.java:26)
    This is my context.xml configuration:
    Code:
    <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan" value="it.nikeconsulting.chirp.domain" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
    </bean>
    	
    <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
        <property name="nestedTransactionAllowed" value="true" />
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
        </property>
    </bean>
    	
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" id="jpaVendorAdapter">
        <property name="showSql" value="true" />
        <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
     </bean>

  • #2
    If you get this exception that indicates your transaction configuration is flawed.

    My guess, you are scanning for components twice, leading to troubled transaction management.

    To use entities in your jsp in general you want to use an OpenEntityManagerInViewFilter (or Interceptor) to keep the session open until the page is rendered. Also depending on your architecture the method you currently use doesn't have to be wrong. In general the model used in the view doesn't represent the model used in the service (I suggest you do some googling for CQRS and DDD bounded contexts) and you want some kind of read-only model (view model or whatever you want to name it) seperate from your business model.

    Comment


    • #3
      Yes, it was...Thank you! You answered more than 1 question that I had. I've already was looking for DDD and CQRS, do you have some good references??

      Cheers
      Originally posted by Marten Deinum View Post
      If you get this exception that indicates your transaction configuration is flawed.

      My guess, you are scanning for components twice, leading to troubled transaction management.

      To use entities in your jsp in general you want to use an OpenEntityManagerInViewFilter (or Interceptor) to keep the session open until the page is rendered. Also depending on your architecture the method you currently use doesn't have to be wrong. In general the model used in the view doesn't represent the model used in the service (I suggest you do some googling for CQRS and DDD bounded contexts) and you want some kind of read-only model (view model or whatever you want to name it) seperate from your business model.

      Comment

      Working...
      X