I am developing an application using Spring Data JPA with Transactions. Although the version of Spring I'm on (4.0.0) is able to use JavaConfig, I prefer to stick with XML.
I have this config:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<jpa:repositories base-package="repo"/>
<context:component-scan base-package="service" />
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/staffing?transformedBitIsBoolean=true"/>
<property name="username" value="root"/>
<property name="password" value="vivupdip1`"/>
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="database" value="MYSQL"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="packagesToScan" value="model"/>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.hbm2ddl.auto" value="validate"/>
<entry key="hibernate.format_sql" value="true" />
</map>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
My single (so far) repository is this:
package repo;
import org.springframework.data.jpa.repository.JpaRepository;
import model.Volunteer;
public interface VolunteerRepo extends JpaRepository<Volunteer, Integer> {
}
I also have a Service interface in the service
package:
public interface VolunteerService {
public List<Volunteer> findAll();
}
and the implementation:
@Service
@Transactional
public class VolunteerServiceImpl implements VolunteerService {
@Autowired VolunteerRepo repo;
public List<Volunteer> findAll() {
return repo.findAll();
}
}
called from a Controller
in the controller
package:
@RestController
public class VolunteerController {
@Autowired VolunteerService vs;
@RequestMapping(value = "/volunteers")
List<Volunteer> getVolunteers() {
return vs.findAll();
}
}
The Volunteer
domain object is quite complex and is related to various other domain objects.
When I issue the correct request in the browser, I get the following exception:
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: model.Volunteer.volunteerSessions, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->model.Volunteer["sessions"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: model.Volunteer.volunteerSessions, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->model.Volunteer["sessions"])
which, as far as I understand, is moaning about not having a session, which (I think) can be fixed by configuring transactions properly. But, my attempt as configuring transactions seems not to be correct, but I cannot work out why.
Your errormessage stating that there is no session available is preceded by:
Could not write JSON
This tells you that the proxy was accessed when attempting to serialize the object into JSON. This is happening in your RestController
, which indeed is not transactional, so has no session bound, and that is why the lazy-loading failed.
Possible solutions are:
VolunteerServiceImpl