Spring boot 2 data JPA: Transaction not rolling back [duplicate] - spring

I recently moved from Hibernate to JPA. Now I notice two things in my code.
Methods in my services do not need #Transactional anymore to perform insertion to the database.
Transaction never get rolled back even if there's any exception.
applicationContext.xml
<?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:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
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-1.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.myapp.service, com.myapp.batch,com.myapp.auth" />
<!-- Configure the data source bean -->
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="dataSourceProperties" >
<props>
<prop key="url">jdbc:mysql://localhost:3306/app?zeroDateTimeBehavior=convertToNull</prop>
<prop key="user">user</prop>
<prop key="password">pass</prop>
</props>
</property>
<property name="dataSourceClassName"
value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<constructor-arg ref="hikariConfig" />
</bean>
<!-- Create default configuration for Hibernate -->
<bean id="hibernateJpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
<!-- Configure the entity manager factory bean -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.myapp.persist" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.c3p0.timeout">100</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.springframework.jdbc.datasource.init.DataSourceInitializer"
depends-on="entityManagerFactory">
<property name="dataSource" ref="dataSource" />
<property name="databasePopulator">
<bean
class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
<property name="scripts" value="classpath:initial_data.sql" />
<property name="continueOnError" value="true" />
</bean>
</property>
</bean>
<jpa:repositories base-package="com.myapp.repositories"
entity-manager-factory-ref="entityManagerFactory" />
<!-- Enable annotation driven transaction management -->
<tx:annotation-driven />
<task:annotation-driven />
</beans>
NetworkService.java
#Service
public class AdminUserManagementService {
#Autowired
UserRepository userRepository;
#Autowired
UserService userService;
#Autowired
RequestRegisterHistoryRepository requestRegisterHistoryRepository;
#Autowired
#Transactional(rollbackFor=Exception.class)
public User saveUser(UserBO userBO){
RequestRegisterHistory requestRegisterHistory = new RequestRegisterHistory();
User user = new User();
// ..
requestRegisterHistoryRepository.save(requestRegisterHistory);
userRepository.save(user);
return user;
}
}
mvc-dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="sec://www.springframework.org/schema/mvc"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<context:component-scan base-package="com.myapp.controller" />
<!-- Enables the Spring MVC #Controller programming model -->
<mvc:annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving
up static resources in the ${webappRoot}/resources directory -->
<mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/" />
<mvc:resources mapping="/resources/**" location="resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources
in the /WEB-INF/views directory -->
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
<beans:property name="order" value="1" />
</beans:bean>
<beans:bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<beans:property name="favorPathExtension" value="false" />
<beans:property name="favorParameter" value="true" />
<beans:property name="parameterName" value="mediaType" />
<beans:property name="ignoreAcceptHeader" value="true"/>
<beans:property name="useJaf" value="false"/>
<beans:property name="defaultContentType" value="application/json" />
<beans:property name="mediaTypes">
<beans:map>
<beans:entry key="json" value="application/json" />
<beans:entry key="xml" value="application/xml" />
</beans:map>
</beans:property>
</beans:bean>
<mvc:interceptors>
<beans:bean
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang" />
</beans:bean>
<beans:bean class="com.myapp.component.AppInterceptor" />
</mvc:interceptors>
<beans:bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
<beans:property name="supportedMediaTypes" value="image/jpeg" />
</beans:bean>
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- setting maximum upload size -->
<beans:property name="maxUploadSize" value="99999999999" />
</beans:bean>
</beans:beans>
I am using Spring Version : 4.1.4 and MySQL Table : MyISAM
Stacktrace
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:248)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:214)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy37.save(Unknown Source)
at com.myapp.service.AdminUserManagementService.saveUser(AdminUserManagementService.java:460)
at com.myapp.service.AdminUserManagementService$$FastClassBySpringCGLIB$$f21244b7.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
How do I configure so I would require #Transactional annotation and any transaction get rolled back during exceptions ?

The issue was with table engine that's MyISAM. The transaction is able to rollback after I changed the engine to InnoDB.
Setting the hibernate.dialect to org.hibernate.dialect.MySQLInnoDBDialect ensure the creation of table with InnoDBin the future.

Related

Error with Spring5+hibernate+jpa+hikaricp xml configuration

Please help. The below is my XML configuration file. My application runs properly. But it says no database selected when call database.
The exception looks like below:
2018-03-24 13:44:17 DEBUG SqlExceptionHelper:139 - could not extract ResultSet [n/a]
java.sql.SQLException: No database selected
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4120)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4052)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2794)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2322)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
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/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="app.sphi" />
<mvc:resources mapping="/res/**" location="/WEB-INF/res/" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<property name="poolName" value="springHikariCP" />
<property name="connectionTestQuery" value="SELECT 1" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/testdb?useUnicode=true" />
<property name="dataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<!-- Create default configuration for Hibernate -->
<bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
</bean>
<!-- Configure the entity manager factory bean -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
<!-- Set JPA properties -->
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
</props>
</property>
<!-- Set base package of your entities -->
<property name="packagesToScan" value="app.sphi.model" />
<!-- Set share cache mode -->
<property name="sharedCacheMode" value="ENABLE_SELECTIVE" />
<!-- Set validation mode -->
<property name="validationMode" value="NONE" />
</bean>
<!-- Configure the transaction manager bean -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Enable annotation driven transaction management -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Configure Spring Data JPA and set the base package of the repository interfaces -->
<jpa:repositories base-package="app.sphi.repo"
transaction-manager-ref="transactionManager"
entity-manager-factory-ref="entityManagerFactory" />
</beans>
I will be pleased for any suggestion.
Do not configure both jdbcUrl and dataSourceClassName, pick one style or the other. In this case, I suggest you stick with jdbcUrl.

Spring #Transactional not committing records

I use Spring with Hibernate. I am using following configurations. When I try to save through Spring transaction, the record never commits.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
<context:component-scan base-package="com.wpt.controllers,com.wpt.dao" />
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<bean id="viewResolver"
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="wptDatasource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/wp" />
<property name="username" value="user" />
<property name="password" value="pass" />
</bean>
<bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="wptDatasource" />
<property name="packagesToScan" value="com.wpt.models" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="hibernate4AnnotatedSessionFactory">
</bean></beans>
MyControllerClass
#Transactional
#RequestMapping(...)
public String saveRecords(#ModelAttribute("orderObj") Order order){
for(Item item : order.getItems()){
itemDAO.save(item);
}
return "saveSuccess";
}
MyDAOClass
public void save(Item item){
session = sf.openSession();
session.save(item);
session.close();
}
The above #Transactional configuration not committing the record. But if I remove #Transactional from spring controller and use Hibernate transaction as below, the record commits.
public void save(Item item){
session = sf.openSession();
Transaction tx = session.beginTransaction();
session.persist(item);
tx.commit();
session.close();
}
This class commits the record.
I've gone through some forums and it's mentioned that #Transactional will take care of committing records. What mistake I am doing here? Can someone help?
Thanks in advance.
It worked after I have added <tx:annotation-driven /> annotation to my configuration xml & removed hibernate.current_session_context_class from hibernateSessionFactory bean. Given the changes below.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.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">
<context:component-scan base-package="com.wpt.controllers,com.wpt.dao" />
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<bean id="viewResolver"
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="wptDatasource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/wp" />
<property name="username" value="user" />
<property name="password" value="pass" />
</bean>
<bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="wptDatasource" />
<property name="packagesToScan" value="com.wpt.models" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<!-- <prop key="hibernate.current_session_context_class">thread</prop> -->
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="hibernate4AnnotatedSessionFactory">
</bean>
</beans>
Then I have included org.springframework.transaction.annotation.Transactional annotation to all my service methods & removed all transactions from my DAO classes.
public void save(Item item){
//session = sf.openSession();
session.save(item);
//session.close();
}
Thanks all for your help.

Spring ACL issue with disk store ehcache

I'm trying to implement Spring ACL, but I encountered an issue to which i have no clue of how to solve.
We have a running configuration of echache which is loaded from the following spring context.
<?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:sec="http://www.springframework.org/schema/security"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
xmlns:task="http://www.springframework.org/schema/task" xmlns:aop="http://www.springframework.org/schema/aop"
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/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- Support annotation configuration -->
<context:annotation-config />
<context:property-placeholder location="META-INF/test.properties" ignore-unresolvable="true" ignore-resource-not-found="true" />
<!-- Database access -->
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${db.iwh.driver}" />
<property name="url" value="${db.iwh.url}" />
<property name="username" value="${db.iwh.username}" />
<property name="password" value="${db.iwh.password}" />
<property name="initialSize" value="${db.iwh.initialConnections}" />
<property name="maxActive" value="${db.iwh.maxConnections}" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="datasource"/>
</bean>
<!-- JPA with Hibernate -->
<util:list id="productEntityPackages"/> <!-- Placeholder -->
<util:list id="projectEntityPackages"/> <!-- Placeholder -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="datasource"/>
<property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
<property name="jpaVendorAdapter">
<bean class="dk.intelligentsystems.platform.util.spring.ISHibernateJpaVendorAdapter">
<property name="databasePlatform" value="${db.iwh.dialect}"/>
<property name="showSql" value="${db.iwh.show_sql}"/>
<property name="hbm2ddl" value=""/>
<!-- <property name="hbm2ddlImportFiles" value="''"/> -->
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.generate_statistics">false</prop>
<prop key="hibernate.cache.default_cache_concurrency_strategy">read-write</prop>
<prop key="net.sf.ehcache.configurationResourceName">/META-INF/ehcache.xml</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
<!--prop key="javax.persistence.sharedCache.mode">DISABLE_SELECTIVE</prop-->
</props>
</property>
<!--property name="packagesToScan" ref="entityManagerPackages"/-->
<!-- Managing transactions explicitly -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="txInterceptor" class="dk.intelligentsystems.platform.tx.ISTransactionInterceptor" />
<aop:config>
<!-- Add custom transaction interceptor to all #Transactional methods -->
<aop:pointcut id="transactionalMethod" expression="#annotation(org.springframework.transaction.annotation.Transactional) || within(#org.springframework.transaction.annotation.Transactional *)"/>
<aop:advisor pointcut-ref="transactionalMethod" advice-ref="txInterceptor" order="1"/>
</aop:config>
<!-- Task scheduling -->
<task:scheduler id="taskScheduler" pool-size="8"/>
</beans>
The ehcache looks as:
<?xml version="1.0" encoding="UTF-8"?>
<!-- See http://ehcache.org/documentation/user-guide/hibernate -->
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
maxElementsOnDisk="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
statistics="true"
memoryStoreEvictionPolicy="LRU"/>
<cache name="dk.platform.model.Alarm"
maxElementsInMemory="2000"
eternal="false"
timeToIdleSeconds="360"
timeToLiveSeconds="360">
</cache>
...
The ACL is loaded in this application context (Bottom part stolen from spring security contacts sample):
<?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:util="http://www.springframework.org/schema/util"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<import resource="spring-test-base.xml"/>
<sec:global-method-security pre-post-annotations="enabled" secured-annotations="disabled" jsr250-annotations="disabled" proxy-target-class="true">
<sec:expression-handler ref="expressionHandler" />
</sec:global-method-security>
<bean id="expressionHandler"
class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<property name="permissionEvaluator">
<bean id="permissionevaluator" class="dk.company.util.AuthorizationProvider">
</bean>
</property>
</bean>
<!-- ========= ACL SERVICE DEFINITIONS ========= -->
<bean id="aclCache" class="org.springframework.security.acls.domain.EhCacheBasedAclCache">
<constructor-arg>
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />
</property>
<property name="cacheName" value="aclCache"/>
</bean>
</constructor-arg>
</bean>
<bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
<constructor-arg ref="datasource"/>
<constructor-arg ref="aclCache"/>
<constructor-arg>
<bean class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
<constructor-arg>
<bean class="org.springframework.security.core.authority.SimpleGrantedAuthority">
<constructor-arg value="ROLE_ADMINISTRATOR"/>
</bean>
</constructor-arg>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
</constructor-arg>
</bean>
<bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
<constructor-arg ref="datasource"/>
<constructor-arg ref="lookupStrategy"/>
<constructor-arg ref="aclCache"/>
</bean>
</beans>
When I try to run the application I get the following exception:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:122)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:312)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
// Some thousand stack frames...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cache.ehcache.EhCacheFactoryBean#51e88ff6' defined in class path resource [META-INF/spring-authorization-test.xml]: Invocation of init method failed; nested exception is net.sf.ehcache.CacheException: aclCache Cache: Could not create disk store. This CacheManager configuration does not allow creation of DiskStores. If you wish to create DiskStores, please configure a diskStore path.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1482)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:271)
... 45 more
Caused by: net.sf.ehcache.CacheException: aclCache Cache: Could not create disk store. This CacheManager configuration does not allow creation of DiskStores. If you wish to create DiskStores, please configure a diskStore path.
at net.sf.ehcache.store.compound.factories.DiskOverflowStorageFactory.getDataFile(DiskOverflowStorageFactory.java:79)
at net.sf.ehcache.store.compound.factories.DiskOverflowStorageFactory.<init>(DiskOverflowStorageFactory.java:71)
at net.sf.ehcache.store.compound.impl.OverflowToDiskStore.create(OverflowToDiskStore.java:63)
at net.sf.ehcache.Cache.initialise(Cache.java:1113)
at net.sf.ehcache.CacheManager.addCacheNoCheck(CacheManager.java:1081)
at net.sf.ehcache.CacheManager.addCache(CacheManager.java:987)
at org.springframework.cache.ehcache.EhCacheFactoryBean.afterPropertiesSet(EhCacheFactoryBean.java:333)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1541)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1479)
... 48 more
I tried removing the <diskStore path="java.io.tmpdir"/> line in the ehcache, but to no avail.
EDIT
Spring version: 3.2.4.RELEASE
Ehcache version: 4.1.9.Final
According to EhCache documentation, you can turn off usage of disk for a cache by setting the overflowToDisk attribute to false. So you could try :
<defaultCache
maxElementsInMemory="10000"
overflowToDisk="false"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
statistics="true"
memoryStoreEvictionPolicy="LRU"/>

spring security mysuccessHandler

using spring security to protect my RESt WebService
i have one usue which is
this class org.rest.security.MySavedRequestAwareAuthenticationSuccessHandler
<?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:c="http://www.springframework.org/schema/c"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<security:http entry-point-ref="restAuthenticationEntryPoint">
<security:intercept-url pattern="/api/admin/**" access="ROLE_ADMIN"/>
<security:custom-filter ref="myFilter" position="FORM_LOGIN_FILTER"/>
</security:http>
<bean id="mydataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://127.0.0.1:3306/VconfGwDb?autoReconnect=true" />
<property name="username" value="***" />
<property name="password" value="****" />
<property name="validationQuery" value="Select 1"></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="mydataSource" />
<property name="annotatedClasses">
<list>
<value>com.alpha.vconf.model.Participation</value>
<value>com.alpha.vconf.model.ParticipationId</value>
<value>com.**.**.model.***</value>
<value>com.**.*.model.**</value>
<value>com.***.**.model.**</value>
<value>com.**.**.model.***</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="myFilter" class=
"org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationSuccessHandler" ref="mySuccessHandler"/>
</bean>
<bean id="mySuccessHandler"
class="org.rest.security.MySavedRequestAwareAuthenticationSuccessHandler"/>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider>
<security:user-service>
<security:user name="temporary" password="temporary" authorities="****"/>
<security:user name="***" password="***" authorities="***"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
<tx:annotation-driven transaction-manager="transactionManager" />
<context:annotation-config />
<context:component-scan base-package="com.***.***"></context:component-scan>
</beans>
so the problem is that :- Class 'org.rest.security.MySavedRequestAwareAuthenticationSuccessHandler' not
found how can i resolve this issue
org.rest.security.MySavedRequestAwareAuthenticationSuccessHandler must be either in WEB-INF/classes or in a JAR in WEB-INF/lib but I guess you know that. What's the exception you're getting? Note that there's a difference between NoClassDefFoundError and ClassNotFoundException.
EDIT
In any case your success handler must be an implementation of org.springframework.security.web.authentication.AuthenticationSuccessHandler. You either provide your own (changing the obscure com.rest.yadayada class name to the name of your class) or remove this line
<property name="authenticationSuccessHandler" ref="mySuccessHandler"/>
to use the default success handler.

Spring VelocityViewResolver not resolving

I get the following error when trying to set up a Spring project with Velocity.
PageNotFound - No mapping found for HTTP request with URI [/SpringMVCVelocity/Enquiries/viewAllEnquiries] in DispatcherServlet with name 'mvc-dispatcher'
I have set up the spring context.xml as-
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.3.xsd">
<context:component-scan base-package="ecommerce.dao" />
<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath" value="/WEB-INF/view/"/>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
<property name="cache" value="false"/>
<property name="prefix" value=""/>
<property name="suffix" value=".vm"/>
<property name="order" value="-1"/>
<property name="exposeSpringMacroHelpers" value="true"></property>
</bean>
<mvc:annotation-driven/>
<!-- Forwards requests to the "/" resource to the "welcome" view -->
<mvc:view-controller path="/" view-name="welcome"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="ecommerce"/>
</bean>
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!-- Configures Handler Interceptors -->
<mvc:interceptors>
<!-- Changes the locale when a 'locale' request parameter is sent; e.g. /?locale=de -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</mvc:interceptors>
<!-- Saves a locale change using a cookie -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" />
<!-- Application Message Bundle -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages/messages" />
<property name="cacheSeconds" value="0" />
</bean>
<!--
FLOW HANDLING
-->
<!-- Enables FlowHandler URL mapping -->
<bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
</bean>
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry"/>
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry" />
<property name="order" value="-1" />
</bean>
<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
<webflow:flow-location path="/WEB-INF/view/flows/flow.xml"/>
</webflow:flow-registry>
<webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="mvcViewFactoryCreator" />
<bean id="mvcViewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
<property name="viewResolvers" ref="viewResolver" />
</bean>
<!--
Bean Injections
-->
<bean id="carModelDao" class="ecommerce.dao.CarModelDao"/>
<bean id="carController" class="ecommerce.controller.CarController">
<property name="carModelDao" ref="carModelDao"/>
</bean>
<bean id="veloController" class="ecommerce.controller.VelocityController">
<property name="carModelDao" ref="carModelDao"/>
</bean>
</beans>
My controller is:
#Controller
#RequestMapping("/Enquiries")
#SessionAttributes({"enqList", "search"})
public class EnquiryController {
private static final Logger logger = Logger.getLogger(EnquiryController.class);
private PagedListHolder<Enquiry> enqList = null;
private int pageSize = 10;
#Autowired
private EnquiryDao enquiryDao;
#RequestMapping("/viewAllEnquiries")
public String getAllEnquiries(#RequestParam(required=false) String page, Model model) {
if ("next".equals(page) && enqList != null) {
enqList.nextPage();
} else if ("previous".equals(page) && enqList != null) {
enqList.previousPage();
} else {
// well there is no page parameter, so it must be a new request
enqList = new PagedListHolder<Enquiry>(enquiryDao.getAllEnquiries());
enqList.setPageSize(pageSize);
}
model.addAttribute("search", new Search());
model.addAttribute("enqList", enqList);
return "viewAllEnquiries";
}
This controller is not even called. It does however successfully manage to resolve the welcome view with:
<mvc:view-controller path="/" view-name="welcome"/>
Problem solved,
I wasn't scanning the controller (context:component-scan) and had not wired the bean either in the Spring context.
So to fix it, I added it via spring injection:
<bean id="enquiryDao" class="ecommerce.dao.EnquiryDao"/>
<bean id="enquiryController" class="ecommerce.controller.EnquiryController">
<property name="enquiryDao" ref="enquiryDao"/>
</bean>

Resources