I am trying to integrate Spring+Hibernate4, but when I access my DAOs I get a nullPointerException on the sessionFactory object.
This is my AbstractDao:
#Repository
public class AbstractDaoHibernateImpl {
private SessionFactory sessionFactory;
public AbstractDaoHibernateImpl() {
}
#Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
protected Session getSession() {
return getSessionFactory().getCurrentSession();
}
protected Order getOrder(String orderBy, boolean isOrderAsc) {
if (isOrderAsc)
return Order.asc(orderBy);
else
return Order.desc(orderBy);
}
}
This is my entity bean config:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- transacciones -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="SessionFactory"/>
</bean>
<!--Beans de los servicios de la aplicacion -->
<bean id="userService" class="com.app.service.user.UserServiceImpl"/>
<bean name="userDAO" class="com.app.model.user.dao.UserDaoImpl">
<property name="sessionFactory" ref="SessionFactory" />
</bean>
<bean id="SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
</beans>
And this is the rest of my appContext
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<context:component-scan base-package="com.app.controllers" />
<mvc:annotation-driven />
<context:annotation-config />
<tx:annotation-driven transaction-manager="transactionManager"/>
<import resource="applicationDatasource.xml" />
<import resource="applicationEntityBean.xml" />
</beans>
And finally this is my Service object:
#Service
public class UsuarioServiceImpl implements IUsuarioService {
#Autowired
private IUserDao userDao;
public List<User> getUsers() throws GenericDataBaseException {
return userDao.findAll();
}
}
Shouldn't the sessionFactory object be injected like this?
This is the whole stack trace:
java.lang.NullPointerException
at es.plexus.core.dao.impl.GenericDaoHibernateImpl.findAll(GenericDaoHibernateImpl.java:243)
at es.plexus.service.usuario.UsuarioServiceImpl.getUsuarios(UsuarioServiceImpl.java:20)
at es.plexus.controller.usuario.UsuarioController.listUsuarios(UsuarioController.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:722)
EDIT: userDao:
public class UserDaoImpl extends GenericDaoHibernateImpl<Usuario, Long> implements IUserDao {
}
which extends GenericDao:
public class GenericDaoHibernateImpl<E, PK extends Serializable> extends AbstractDaoHibernateImpl implements GenericDao<E, PK> {
private Class<E> entityClass;
public GenericDaoHibernateImpl() {
this.entityClass = (Class<E>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public List<E> findAll() throws GenericDataBaseException {
try {
Criteria criteria = getSession().createCriteria(getEntityClass());
List<E> result = criteria.list();
/*
* if (result == null || result.size() == 0) throw new
* NoSearchResultException("", getEntityClass().getName());
*/
return result;
} catch (Throwable t) {
Collection<Object> args = new ArrayList<Object>();
throw exceptionHandler.handle(this, t, "findAll", args);
}
}
(...)
}
I see no transactions defined anywhere in your code.
In this case I recommend you put them on your service method :
#Transactional(readOnly = true)
public List<User> getUsers() throws GenericDataBaseException {
return userDao.findAll();
}
But you seem to be developing a rather complex class hierarchy, all you need is one generic repository and then instantiate that for different types. You don't have to use a service class, they are only recommended when using multiple aggregate roots/complex logic - not a simple getter.
Let me take a guess.
Is your DAO under the package com.app.controllers? If not add your dao package to the component scan as in <context:component-scan base-package="com.app.controllers, com.app.model.user.dao" />
Related
What is wrong?
I was wrote two controllers but don't understand what is wrong.
Don't know how to make correct for working both controller correct.
Type Exception Report
Message Servlet.init() for servlet [mvc-dispatcher] threw exception
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
javax.servlet.ServletException: Servlet.init() for servlet [mvc-dispatcher] threw exception
rg.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'bookController' bean method
public java.lang.String com.jackson.BookController.editBook(int,org.springframework.ui.Model)
to {[/edit/{id}],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}: There is already 'authorController' bean method
public java.lang.String com.jackson.AuthorController.editAuthor(int,org.springframework.ui.Model) mapped.
package com.jackson;
#Controller
public class AuthorController {
private AuthorService authorService;
#Autowired(required = true)
#Qualifier(value = "authorService")
public void setBookService(AuthorService authorService) {
this.authorService = authorService;
}
#RequestMapping
(value = "authors", method = RequestMethod.GET)
public String listAuthors(Model model){
model.addAttribute("author", new Author());
model.addAttribute("listAuthors", this.authorService.list());
return "authors";
}
#RequestMapping
(value = "authors/add", method = RequestMethod.POST)
public String addAuthor(#ModelAttribute("author") Author author){
if(author.getId() == 0){
this.authorService.addAuthor(author);
}else {
this.authorService.updateAuthor(author);
}
return "redirect:/authors";
}
#RequestMapping("/remove/{id}")
public String removeAuthor(#PathVariable("id") int id){
this.authorService.removeAuthor(id);
return "redirect:/authors";
}
#RequestMapping("/edit/{id}")
public String editAuthor(#PathVariable("id") int id, Model model){
model.addAttribute("author", this.authorService.getAuthorById(id));
model.addAttribute("listBooks", this.authorService.list());
return "authors";
}
#RequestMapping("authordata/{id}")
public String authorData(#PathVariable("id") int id, Model model){
model.addAttribute("author", this.authorService.getAuthorById(id));
return "authordata";
}
}
In my opinion all code working right but still understand whats wrong
package com.jackson;
#RestController
public class BookController {
private BookService bookService;
#Autowired(required = true)
#Qualifier(value = "bookService")
public void setBookService(BookService bookService) {
this.bookService = bookService;
}
#RequestMapping(value = "books", method = RequestMethod.GET)
public String listBooks(Model model){
model.addAttribute("book", new Book());
model.addAttribute("listBooks", this.bookService.listBooks());
return "books";
}
#RequestMapping(value = "/books/add", method = RequestMethod.POST)
public String addBook(#ModelAttribute("book") Book book){
if(book.getId() == 0){
this.bookService.addBook(book);
}else {
this.bookService.updateBook(book);
}
return "redirect:/books";
}
#RequestMapping("/remove/{id}")
public String removeBook(#PathVariable("id") int id){
this.bookService.removeBook(id);
return "redirect:/books";
}
#RequestMapping("edit/{id}")
public String editBook(#PathVariable("id") int id, Model model){
model.addAttribute("book", this.bookService.getBookById(id));
model.addAttribute("listBooks", this.bookService.listBooks());
return "books";
}
#RequestMapping("bookdata/{id}")
public String bookData(#PathVariable("id") int id, Model model){
model.addAttribute("book", this.bookService.getBookById(id));
return "bookdata";
}
}
In my opinion all code working right but still understand whats wrong
mvc-dispacther-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.jackson"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
// database config
<!-- Hibernate 4 SessionFactory Bean definition -->
<bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="annotatedClasses">
<list>
<value>com.jackson.Book</value>
<value>com.jackson.Author</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!--BookDao and BookService beans-->
<bean id="bookDao" class="com.jackson.BookDao">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</bean>
<bean id="bookService" class="com.jackson.BookService">
<property name="bookDao" ref="bookDao"/>
</bean>
<bean id="authorDao" class="com.jackson.AuthorDao">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</bean>
<bean id="authorService" class="com.jackson.AuthorService">
<property name="authorDao" ref="authorDao"/>
</bean>
<context:component-scan base-package="com.jackson"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</bean>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
</beans>
web.xml
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>com.jackson.Book Manager</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Your controllers have conflict mapping methods. Don't declare same request mapping method on different controllers.
BookController needs to have #Controller instead of #RestController.
I have this problem, I'm working with Spring, Hibernate, JPA and serverless framework.
When I invoke the class form the console I got this error "
"errorMessage": "No bean named 'wizardDao' is defined",
"errorType": "org.springframework.beans.factory.NoSuchBeanDefinitionException",
"stackTrace": [
"org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:694)",
"org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1168)",
"org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:281)",
"org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)",
"org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)",
"com.serverless.dao.Handler.handleRequest(Handler.java:30)",
"com.serverless.dao.Handler.handleRequest(Handler.java:17)"
but if I prove the class in Eclipse with I main class there's not problema. I don't know what is going wrong
this is my applicationContext
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">
<context:component-scan base-package="com.serverless" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="Things-serverless" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<task:scheduler id="taskScheduler" />
<task:executor id="taskExecutor" pool-size="1" />
<task:annotation-driven executor="taskExecutor"
scheduler="taskScheduler" />
<!-- <bean id="serviceBean" class="com.serverless.test" /> -->
</beans>
this is my dao class
#Component
public class WizardDao extends ForwardedMessageDao {
private static final long serialVersionUID = 5302145657830590489L;
/**
* Get all wizards from data base.
*
* #param
* #return List of wizards
*/
#SuppressWarnings("unchecked")
public List<Wizard> getAllWizards() {
Query query = getEmf().createQuery("FROM Wizard");
System.out.println("aqui ");
return (List<Wizard>) query.getResultList();
}
}
and this is my handdler class
#Service
#Transactional
public class Handler implements RequestHandler<Map<String, Object>, ApiGatewayResponse> {
private static final Logger LOG = Logger.getLogger(Handler.class);
#Autowired
private WizardDao wizardDao;
#Override
public ApiGatewayResponse handleRequest(Map<String, Object> input, Context context) {
BasicConfigurator.configure();
Map<String, Wizard> response = new HashMap<>();
Response responseBody = new Response("start", response);
try {
wizardDao = Application.getBean(WizardDao.class);
List<Wizard> listWizard = wizardDao.getAllWizards();
for (Wizard wizard : listWizard) {
response.put("" + wizard.getIdWizard(), wizard);
}
responseBody.setInput(response);
} catch (Exception e) {
responseBody.setMessage("Fail: " + e.getMessage());
}
LOG.info("received: " + input);
return ApiGatewayResponse.builder().setStatusCode(200).setObjectBody(responseBody)
.setHeaders(Collections.singletonMap("fur", "this sheep")).build();
}
}
and this is my entityManager Class
public class EntityManagerDao implements Serializable {
private static final long serialVersionUID = -6969245506190987187L;
#PersistenceContext(unitName = "Things-serverless")
private EntityManager em;
/**
* #return the em
*/
public EntityManager getEmf() {
return em;
}
}
İ developed a web application using spring and hibernate. This is pretty huge app and i have to get some services from outside of controllers as well. For this i used xmlclasspathcontext to get beans at the same time.
Currently i am using threadlocal and opensession. So far i do not have problem except reading old data when update somethings. İ know this happens because of threadlocal keep current session.
What i want to learn is, İF i remove threadlocal and use öpensession and close session is it a good approach?
Because i cant use getcurrentsession with controllers and getbeans at the same time. İam getting no session found err at the xmXML get bean side. Is there a way to get getcurrentsession at both side? Or do i haveto use open and close session approach? What İF i do not close each opwnsession?
<?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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="com.yupsoft.grid" />
<tx:annotation-driven transaction-manager="hibernateTransactionManager"/>
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/grid" />
<property name="username" value="myuser" />
<property name="password" value="mypass" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.yupsoft.yupsoft.model.LanguageTextParameter</value>
<value>com.yupsoft.yupsoft.model.LoginHistory</value>
<value>com.yupsoft.yupsoft.model.Session</value>
<value>com.yupsoft.yupsoft.model.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!--
<prop key="hibernate.connection.autocommit">false</prop>
-->
<prop key="hibernate.connection.charSet">utf8</prop>
<prop key="hibernate.connection.characterEncoding">utf8</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.autoReconnect">true</prop>
<prop key="current_session_context_class">thread</prop>
<prop key="hibernate.connection.pool_size">1</prop>
<prop key="hibernate.c3p0.min_size">10</prop>
<prop key="hibernate.c3p0.max_size">100</prop>
<prop key="hibernate.c3p0.timeout">1800</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="hibernate.c3p0.idle_test_period">30</prop>
<prop key="hibernate.c3p0.acquire_increment">1</prop>
<prop key="hibernate.c3p0.max_statements">0</prop>
<prop key="hibernate.c3p0.preferredTestQuery">select 1;</prop>
<prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
<prop key="hibernate.connection.isolation">8</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
</props>
</property>
</bean>
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
This is Controller class that I am getting requests
#Controller
public class UserController {
#Autowired
private UserService userService;
#Autowired
private LoginHistoryService loginHistoryService;
#RequestMapping(value = "/loginAttempt", method = RequestMethod.POST)
public #ResponseBody
String loginAttempt(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String userName = request.getParameter("userName");
String password = request.getParameter("password");
User user = userService.getByUserNameAndPassword(userName, password);
if (user != null) {
if (user.isActive()) {
LoginHistory loginHistory = new LoginHistory();
loginHistory.setCreated(new Date());
loginHistory.setIpAddress(request.getRemoteAddr());
loginHistory.setSessionId(request.getSession().getId());
loginHistory.setAccountVerified(Boolean.TRUE);
loginHistory.setUser(user);
boolean loginHistoryCreated = loginHistoryService.create(loginHistory);
if (loginHistoryCreated) {
return "ok";
} else {
//Error
return "err";
}
} else {
return "err";
}
}
return "ok";
}
}
This is Service layer
#Service("loginHistoryService")
#Transactional(propagation = Propagation.REQUIRED, readOnly = true, isolation = Isolation.SERIALIZABLE)
public class LoginHistoryServiceImpl extends GenericServiceImpl implements LoginHistoryService {
#Autowired
private LoginHistoryDAO loginHistoryDAO;
public LoginHistoryDAO getLoginHistoryDAO() {
return loginHistoryDAO;
}
public void setLoginHistoryDAO(LoginHistoryDAO loginHistoryDAO) {
this.loginHistoryDAO = loginHistoryDAO;
setGenericDAO(loginHistoryDAO);
}
#Transactional(propagation = Propagation.REQUIRED, readOnly = false)
#Override
public boolean create(LoginHistory obj) {
return loginHistoryDAO.create(obj);
}
This part is DAO layer
#Repository("loginHistoryDAO")
public class LoginHistoryDAOImpl extends GenericDAOImpl implements LoginHistoryDAO {
#Autowired
private SessionDAO sessionDAO;
#Override
public boolean create(LoginHistory obj) {
try {
//beginTransaction();
save(obj);
if (obj.isAccountVerified()) {
Session s = new Session();
s.setActive(Boolean.TRUE);
s.setIpAddress(obj.getIpAddress());
s.setCreated(new Date());
s.setSessionId(obj.getSessionId());
s.setUser(obj.getUser());
sessionDAO.save(s);
}
//commitTransaction();
} catch (Exception e) {
handleException(e);
return false;
}
return true;
}
}
And last part is generic part
#SuppressWarnings("unchecked")
#Repository
public abstract class GenericDAOImpl implements GenericDAO {
#Autowired
private SessionFactory sessionFactory;
private final Class<T> persistentClass;
public GenericDAOImpl() {
this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public Class<T> getPersistentClass() {
return persistentClass;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Session getCurrentSession() throws HibernateException {
return sessionFactory.getCurrentSession();
}
#Override
public Transaction beginTransaction() {
return getCurrentSession().beginTransaction();
}
#Override
public void commitTransaction() {
getCurrentSession().getTransaction().commit();
I am trying to replace openSession() to getCurrentSession()
and I require to control beginTransaction() and tx.commit(). Because I have more than one entity to save or update at the same time. So, I need to wrap those intities in a transaction, be sure all done or all did not done.
When I use getCurrentSession() I am getting this error;
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.virdyn.grid.core.system.filter.SessionFilter.doFilter(SessionFilter.java:88)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:317)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:204)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:660)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:412)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy166.create(Unknown Source)
at com.virdyn.grid.controller.UserController.loginAttempt(UserController.java:75)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:421)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:409)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
... 25 more
Caused by: org.hibernate.TransactionException: Transaction not successfully started
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:100)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
... 43 more
I want to cancel ThreadLocal and use getCurrentSession.
What is wrong in here Or do you have other purposes. In fact I can use opensession() and closeSession for any method in all dao's. If I do that is it to slow my system?
I am waiting solutions thanks
I have been trying to integrate between spring and memorydb in junit tests but i keep getting the exception.
org.hibernate.exception.SQLGrammarException: user lacks privilege or object not found: ORDERTABLE
testcontext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
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/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<jdbc:embedded-database id="testDataSource" type="HSQL">
</jdbc:embedded-database>
<context:annotation-config />
<tx:annotation-driven transaction-manager="transactionManager" />
<context:component-scan base-package="com.bidblaze.service.test"/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
</bean>
<!-- Hibernate session factory -->
<bean id="SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
<property name="dataSource">
<ref bean="testDataSource" />
</property>
<property name="packagesToScan" value= MYPACKAGE />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.connection.url">jdbc:hsqldb:mem:projectdb</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="SessionFactory" ref="SessionFactory" />
</bean>
with defining the other beans
My service class:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "/testContext.xml" })
#Transactional
public class TestService {
//ApplicationContext context = new ClassPathXmlApplicationContext(
//"spring-config.xml");
#Autowired
PaypalPaymentsService PaypalService;
#Autowired
private OrderDAO orderDAO ;
#Autowired
private SessionFactory sessionFactory;
private Session extSession;
#Before
#Transactional
public void openSessionExternal() {
extSession = sessionFactory.getCurrentSession();
}
#Test
#Transactional
public void shouldHaveASessionFactory() {
assertNotNull(sessionFactory);
}
#Test
#Transactional
public void shouldHaveASession() {
assertNotNull(extSession);
}
#Test
public void saveOrder(){
Order order = new Order();
order.setOrderId("1");
order.setRecieverEmail("enduser_biz#gmail.com");
order.setAmount((double)2.00);
extSession.save(order);
Order testOrder = (Order) extSession.createQuery("from OrderTable where orderId = ?").setParameter(0, "1").list().get(0);
assertNotNull(testOrder);
}
the Order class :
#Entity
#Table(name="OrderTable")
public class Order {
#Id
#GeneratedValue
#Column(name="orderId")
String orderId;
PS: my Order class has other properties that refer to other classes but i didnt map them neither they are entities as well.
any suggestions
Following this answer, and knowing your XML mapping, I'd suggest the following annotation changes to orderId:
#Id
#GeneratedValue
#Column(name="orderId", columnDefintion="BIGINT")
String orderId;
That's assuming that #GeneratedValue equates to a "native" generator as in your XML. You might need to use an #GenericGenerator instead with a strategy=native instead more like this:
#Id
#GeneratedValue(generator="my-native-generator")
#GenericGenerator(name="my-native-generator", strategy = "native")
#Column(name="orderId", columnDefintion="BIGINT")
String orderId;
I have a problem with the access to a collection from JSP file. Application is based on MVC Spring framework. I put OpenSessionInViewFilter filter to my web.xml. When I want to access to URL with mentioned file, it throws me
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.app.cloud.hibernate.Product.availabilities, no session or session was closed
I use domain driven design in my app. When I changed fetch type in class Product from FetchType.LAZY to FetchType.EAGER, it worked.
stacktrace
SEVERE: Servlet.service() for servlet [spring] in context with path [] threw exception [org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.app.cloud.hibernate.Product.availabilities, no session or session was closed] with root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.app.cloud.hibernate.Product.availabilities, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:119)
at org.hibernate.collection.PersistentSet.isEmpty(PersistentSet.java:169)
at org.apache.el.parser.AstEmpty.getValue(AstEmpty.java:55)
at org.apache.el.parser.AstNot.getValue(AstNot.java:44)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)
at org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:1026)
at org.apache.jsp.WEB_002dINF.jsp.product.products_jsp._jspx_meth_c_005fwhen_005f0(products_jsp.java:321)
at org.apache.jsp.WEB_002dINF.jsp.product.products_jsp._jspx_meth_c_005fchoose_005f0(products_jsp.java:290)
at org.apache.jsp.WEB_002dINF.jsp.product.products_jsp._jspx_meth_c_005fforEach_005f0(products_jsp.java:233)
at org.apache.jsp.WEB_002dINF.jsp.product.products_jsp._jspx_meth_c_005fif_005f0(products_jsp.java:185)
at org.apache.jsp.WEB_002dINF.jsp.product.products_jsp._jspService(products_jsp.java:141)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
at org.apache.jasper.servlet.JspServlet._serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:264)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:811)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:123)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:581)
at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:171)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1686)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
web.xml
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
<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>
<!-- Context parameters -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>WEB-INF/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jExposeWebAppRoot</param-name>
<param-value>false</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
</web-app>
spring-servlet.xml
<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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:annotation-driven />
<tx:annotation-driven />
<context:component-scan base-package="com.app.cloud" />
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="spring-views" />
<property name="order" value="1" />
</bean>
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<property name="order" value="2" />
</bean>
<!-- JDBC -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" p:password="${jdbc.password}" />
<!-- Hibernate -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
ProductService.java
#Transactional
public interface ProductService {
#Transactional
public void add(Product product);
#Transactional
public List<Product> getAll();
#Transactional
public Product get(Integer idProduct);
#Transactional
public void remove(Integer id);
#Transactional
public void edit(Product product);
}
ProductServiceImpl.java
#Service
#Transactional
public class ProductServiceImpl implements ProductService {
#Autowired
private ProductDAO productDAO;
#Transactional
public void add(Product product) {
productDAO.add(product);
}
#Transactional
public List<Product> getAll() {
return productDAO.getAll();
}
#Transactional
public void remove(Integer id) {
productDAO.remove(id);
}
#Transactional
public Product get(Integer idProduct) {
return productDAO.get(idProduct);
}
#Transactional
public void edit(Product product) {
productDAO.edit(product);
}
}
ProductDAO.java
public interface ProductDAO {
public void add(Product product);
public void edit(Product product);
public List<Product> getAll();
public Product get(Integer idProduct);
public void remove(Integer id);
}
ProductDAOImpl.java
#Repository
public class ProductDAOImpl implements ProductDAO {
#Autowired
private SessionFactory sessionFactory;
public void add(Product product) {
sessionFactory.getCurrentSession().save(product);
}
public List<Product> getAll() {
return sessionFactory.getCurrentSession().createQuery("from Product")
.list();
}
public void remove(Integer id) {
Product product = (Product) sessionFactory.getCurrentSession().load(
Product.class, id);
if (null != product) {
sessionFactory.getCurrentSession().delete(product);
}
}
public Product get(Integer idProduct) {
Product product = (Product) sessionFactory.openSession().get(
Product.class, idProduct);
return product;
}
#Override
public void edit(Product product) {
sessionFactory.getCurrentSession().update(product);
}
}
Product.java
#Entity
#Table(name = "product", catalog = "app")
public class Product implements java.io.Serializable {
private Integer idProduct;
#NotEmpty
#Length (min=1,max=70)
private String name;
private Set<Availability> availabilities = new HashSet<Availability>(0);
public Product() {
}
public Product(String name) {
this.category = category;
this.name = name;
this.lastUpdate = lastUpdate;
this.actionFlag = actionFlag;
}
public Product(String name,
Set<Availability> availabilities,
) {
this.name = name;
this.availabilities = availabilities;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id_product", unique = true, nullable = false)
public Integer getIdProduct() {
return this.idProduct;
}
public void setIdProduct(Integer idProduct) {
this.idProduct = idProduct;
}
#Column(name = "name", nullable = false, length = 70)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "product")
public Set<Availability> getAvailabilities() {
return this.availabilities;
}
public void setAvailabilities(Set<Availability> availabilities) {
this.availabilities = availabilities;
}
}
It's very classical error when working with Hibernate.
If you have any lazy-loading proxies your should replace them either with nulls or with real objects before returning from #Transactional context.
The Set or List that is lazy loaded is replaced by the Hibernate with the proxy. The proxy would load the collection first time it is accessed. But what if it is first accessed if you are outside the transactional context? The hibernate session that is referenced by the proxy doesn't exist so you have the error.
If you won't need the collection, set it to null or empty HashSet/ArrayList. If you would need it, call the size() or iterate through the element within transactional context. If you are not sure, provide the API for loading the connection. But don't return objects with uninitialized proxies.
Annotate your Controller as #Transactional. You wont see that error again, You bet!!
Note
Experts say that #Transactional is not to be used on Controller, But I didn't get an answer why?
You can try
#Proxy (lazy = false)
On top of both entity class. It works in my case.