First, i suspect that it's my transaction configuration problem, so i create a simple spring-jdbc project with same transaction configuration, it works fine, then i check the log and find out may be it has something to do with "BeanPostProcessor", see the log below, i've spent lots of time on this, but no luck, any help would be great appreciated, thanks in advance.
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'securityManager' of type [class org.apache.shiro.web.mgt.DefaultWebSecurityManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'configAuthorizationAttributeSourceAdvisor' of type [class org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'transactionAttributeSource' of type [class org.springframework.transaction.annotation.AnnotationTransactionAttributeSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'transactionInterceptor' of type [class org.springframework.transaction.interceptor.TransactionInterceptor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'org.springframework.transaction.config.internalTransactionAdvisor' of type [class org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : com.mchange.v2.log.MLog - MLog clients using log4j logging.
INFO : com.mchange.v2.c3p0.C3P0Registry - Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'dataSource' of type [class com.mchange.v2.c3p0.ComboPooledDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'jdbcTemplate' of type [class org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'fileStoreConfig' of type [class com.myapp.config.FileStoreConfig$$EnhancerByCGLIB$$e05149b7] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'pictureStorage' of type [class com.myapp.core.data.S3FileStorage] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'userDao' of type [class com.myapp.account.dao.UserDao] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'ticketDao' of type [class com.myapp.common.dao.TicketDao] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'ticketService' of type [class com.myapp.common.service.impl.TicketServiceImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'imageDao' of type [class com.myapp.common.dao.ImageDao] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'imageService' of type [class com.myapp.common.service.impl.ImageServiceImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'mailConfig' of type [class com.myapp.config.MailConfig$$EnhancerByCGLIB$$196df0ef] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Add my app config
AppConfig.java
@Configuration
@ComponentScan(basePackages = {"com.myapp.account.web", "com.myapp.account.interceptor", "com.myapp.account.security", "com.myapp.common.web", "com.myapp.email"})
@PropertySource(value = {"classpath:config.properties", "classpath:app.properties"})
public class AppConfig {
}
DataConfig.java
@Configuration
@ComponentScan(basePackages = {"com.myapp.account.service", "com.myapp.account.dao", "com.myapp.common.service", "com.myapp.common.dao"}) // Specifies which package to scan
@EnableTransactionManagement
public class DataConfig {
@Inject
private Environment environment;
@Bean(destroyMethod="close")
public ComboPooledDataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass(environment.getProperty("jdbc.driverClassName"));
cpds.setJdbcUrl(environment.getProperty("jdbc.url"));
cpds.setUser(environment.getProperty("jdbc.username"));
cpds.setPassword(environment.getProperty("jdbc.password"));
cpds.setInitialPoolSize(environment.getProperty("jdbc.initialPoolSize", Integer.class));
cpds.setMinPoolSize(environment.getProperty("jdbc.minPoolSize", Integer.class));
cpds.setMaxPoolSize(environment.getProperty("jdbc.maxPoolSize", Integer.class));
cpds.setCheckoutTimeout(environment.getProperty("jdbc.checkoutTimeout", Integer.class));
cpds.setMaxIdleTime(environment.getProperty("jdbc.maxIdleTime", Integer.class));
cpds.setIdleConnectionTestPeriod(environment.getProperty("jdbc.idleConnectionTestPeriod", Integer.class));
cpds.setAcquireIncrement(environment.getProperty("jdbc.acquireIncrement", Integer.class));
return cpds;
}
@Bean
public NamedParameterJdbcTemplate jdbcTemplate() throws PropertyVetoException {
return new NamedParameterJdbcTemplate(dataSource());
}
/**
* Allows transactions to be managed against the RDBMS using the JDBC API.
* @throws PropertyVetoException
*/
@Bean
public PlatformTransactionManager transactionManager() throws PropertyVetoException {
return new DataSourceTransactionManager(dataSource());
}
/**
@Bean
public DataSourceTransactionManager transactionManager() throws PropertyVetoException {
return new DataSourceTransactionManager(dataSource());
}
*/
@Bean
public UserDao userDao() throws PropertyVetoException {
return new UserDao(jdbcTemplate());
}
@Bean
public TicketDao ticketDao() throws PropertyVetoException {
return new TicketDao(jdbcTemplate());
}
}
SecurityConfig.java
@Configuration
public class SecurityConfig {
@Bean
public Realm configureShiroOAuthDbRealm() {
return new ShiroOAuthDbRealm();
}
@Bean(name = "ehCacheManager")
public EhCacheManager configCacheManager() {
return new EhCacheManager();
}
@Bean(name = "securityManager")
public DefaultWebSecurityManager configSecurityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
ArrayList<Realm> realms = new ArrayList<Realm>();
realms.add(configureShiroPasswordDbRealm());
realms.add(configureShiroTicketDbRealm());
realms.add(configureShiroOAuthDbRealm());
securityManager.setRealms(realms);
securityManager.setCacheManager(configCacheManager());
return securityManager;
}
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor configLifecycleBeanPostProcessor() {
LifecycleBeanPostProcessor lifecycleBeanPostProcessor = new LifecycleBeanPostProcessor();
return lifecycleBeanPostProcessor;
}
/**
* Enable Shiro Annotations for Spring-configured beans.
* Only run after the lifecycleBeanProcessor has run.
*/
@Bean
public DefaultAdvisorAutoProxyCreator configDefaultAdvisorAutoProxyCreator() {
return new DefaultAdvisorAutoProxyCreator();
}
@Bean
public AuthorizationAttributeSourceAdvisor configAuthorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(configSecurityManager());
return authorizationAttributeSourceAdvisor;
}
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean configShiroFilterFactoryBean() {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(configSecurityManager());
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
shiroFilterFactoryBean.setSuccessUrl("/");
Map<String, javax.servlet.Filter> filters = new HashMap<String, javax.servlet.Filter>();
filters.put("authc", new PassThruAuthenticationFilter());
shiroFilterFactoryBean.setFilters(filters);
Map<String, String> filterChainDefinitionMap = new HashMap<String, String>();
filterChainDefinitionMap.put("/control_panel/**", "authc, roles[administrator]");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
}
UserController.java (call testing method testTransaction from userService)
@Controller
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
@Resource(name="userService")
protected UserService userService;
@Resource(name="ticketService")
protected TicketService ticketService;
@RequestMapping(value = "/test-transaction", method = RequestMethod.GET)
public String testTransaction(Model model, HttpServletRequest request) throws Exception {
try{
User user = new User();
user.setUsername("test.transaction");
userService.testTransaction(user);
}catch(Exception e) {
logger.error(e.getMessage(), e);
throw e;
}
return "redirect:/";
}
}
UserServiceImpl.java (testTransaction is a testing method which throw RuntimeException)
@Service("userService")
public class UserServiceImpl implements UserService {
/**
*
*/
private static final long serialVersionUID = 1L;
@Resource
private UserDao userDao;
@Resource
private TicketService ticketService;
@Transactional
public void testTransaction(User user) throws SystemException {
userDao.add(user);
Long.valueOf("Throw RuntimeException");
}
}
UserDao.java
public class UserDao extends BaseDao {
/**
*
*/
private static final long serialVersionUID = 1L;
public UserDao(NamedParameterJdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
private static final String ADD = "INSERT INTO user_(username, email, password_, create_date, modified_date, status_) VALUES(:username, :email, :password, :createDate, :modifiedDate, :status)";
public long add(User user) throws SystemException {
try{
return updateForLongKey(ADD, user);
}catch(Exception e) {
throw processException(e);
}
}
}
BaseDao.java
public class BaseDao implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
protected NamedParameterJdbcTemplate jdbcTemplate;
protected BaseDao(NamedParameterJdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
protected <T> long updateForLongKey(final String sql, T t) {
SqlParameterSource paramSource = new BeanPropertySqlParameterSource(t);
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(sql, paramSource, keyHolder);
return keyHolder.getKey().longValue();
}
public SystemException processException(Exception e) {
if (!(e instanceof DataAccessException)) {
logger.error("Caught unexpected exception " + e.getClass().getName());
}
if (logger.isDebugEnabled()) {
logger.debug(e.getMessage(), e);
}
return new SystemException(e);
}
}