2

i got a problem by using CrudRepository. Example: i have two entities, entity A has a collection of entity B.

class A {
  int id;
  int name;
  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
  Set<B> bs;
  // getters and setters
}
class B {
  int id;
  int name;
  @ManyToOne(mappedBy="bs")
  A a;
  // getters and setters
}

then i got 2 repositories.

class ARepository extends CrudRepository<A, int>{}
class BRepository extends CrudRepository<B, int>{}

but when i got this, i got a org.hibernate.LazyInitializationException, how can i avoid this?

@Service
@Transactional(readOnly=true)
class ServiceImpl implements Service {
@Resource ARepository ar;

@Override
A a = ar.findOne(int id);
}

here is the applicationContext.xml:

<jpa:repositories base-package="com.myproject.repository" />

<context:component-scan base-package="com.myproject.*" />
<context:annotation-config />

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" >
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="persistenceUnitName" value="keep-apm" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="true" />
            <property name="generateDdl" value="true" />
            <property name="database" value="POSTGRESQL"/>
            <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect"/>
        </bean>
    </property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="username" value="root" />
    <property name="password" value="root" />
    <property name="driverClassName" value="org.postgresql.Driver" />
    <property name="url" value="jdbc:postgresql://127.0.0.1:5432/db" />
</bean>
<bean id="sessionFactory" factory-bean="entityManagerFactory" factory-method="getSessionFactory">
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

here is the web.xml

<filter>
    <filter-name>openSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>singleSession</param-name>
        <param-value>true</param-value>
    </init-param>

</filter>
<filter-mapping>
    <filter-name>openSessionInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
    <listener-class>com.myproject.util.LogLocator</listener-class>
</listener>

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

a.bs(the collection) would not be loaded, and always throw out a org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: no session or session was closed

Thank you in advance!!

2 Answers 2

2

You need to use start a transaction, preferably through Spring's Declarative Transaction Management.

In most cases:

  • define a TransactionManager in your XML
  • add this to your XML <tx:annotation-driven />
  • annotate your service method with @Transactional

You can find a sample setup in section Using @Transactional

Sign up to request clarification or add additional context in comments.

1 Comment

Hi Sean, thanks for answering me, but i have already done, everything. i just added more details. please help me with this.
0

Here is the solution:

i can not access the object on my web layer, i should access the lazy loading objects in service layer, which should be in a transaction.

1 Comment

You must be able to access lazily loaded objects in a web view through the use of openSessionInViewFilter because it keeps the session open until the request completes in its entirely. Also, you should not be using singleSession=true. It causes problems (it however does not provide a first-level cache for the entire request).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.