I try to build web application on Java with Spring-MVC and Spring-Security.
In one module where I need get information from database, I can't get SessionFactory.
Form more information, here is my java config and other files source codes:
WebAppConfig.java:
package com.sprsec.init;
import org.hibernate.SessionFactory;
import org.springframework.context.annotation.*;
import org.springframework.context.support.AbstractMessageSource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Properties;
#Configuration
#EnableWebMvc
#EnableTransactionManagement
#ComponentScan("com.sprsec")
#PropertySource("classpath:application.properties")
#ImportResource("classpath:spring-security.xml")
public class WebAppConfig extends WebMvcConfigurerAdapter {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
private static final String PROPERTY_NAME_POOL_SIZE = "hibernate.pool_size";
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
sessionFactoryBean.setHibernateProperties(hibProperties());
return sessionFactoryBean;
}
#Bean
public SessionFactory getSessioFactory(){
return sessionFactory().getObject();
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
properties.put(PROPERTY_NAME_POOL_SIZE, env.getRequiredProperty(PROPERTY_NAME_POOL_SIZE));
return properties;
}
#Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
#Bean(name = "messageSource")
public AbstractMessageSource getMesageSource(){
return new DatabaseMessageSource(sessionFactory().getObject());
}
#Bean
public HandlerInterceptor localeChangeInterceptor(){
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
return localeChangeInterceptor;
}
#Bean
public UrlBasedViewResolver setupViewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/WEB-INF/pages/");
//resolver.setSuffix(".xhtml");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
registry.addInterceptor(localeChangeInterceptor);
}
#Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
cookieLocaleResolver.setDefaultLocale(StringUtils.parseLocaleString("en"));
return cookieLocaleResolver;
}
}
UserDAOImpl.java:
package com.sprsec.dao;
import com.sprsec.model.User;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
#Repository
public class UserDAOImpl implements UserDAO {
#Autowired
private SessionFactory sessionFactory;
private Session getSession(){
return sessionFactory.getCurrentSession();
}
public User getUser(String login) {
List<User> userList = new ArrayList<User>();
Query query = getSession().createQuery("from User u where u.login = :login");
query.setParameter("login", login);
System.out.println(query.getQueryString());
userList = query.list();
if (userList.size() > 0)
return userList.get(0);
else
return null;
}
public User getUserByLoginAndPassword(String login, String password){
Query query = getSession().createQuery("from User u where u.login = :login and u.password = :password");
query.setParameter("login", login);
query.setParameter("password", password);
User user = (User) query.uniqueResult();
return user;
}
}
Here, in UserDAOImpl.java, I retrieve an Exception. SessionFactory is null.
I mind what problem is in my WebAppConfig class because in DatabaseMessageSource.java I retrieve the same exception and I'l add this class in config and over constructor put SessionFactory. I do not want to add there every class that needs this dependency.
Error Message:
Caused by: java.lang.NullPointerException
at com.sprsec.init.DatabaseMessageSource.openSession(DatabaseMessageSource.java:95)
at com.sprsec.init.DatabaseMessageSource.getSQLDictionary(DatabaseMessageSource.java:104)
at com.sprsec.init.DatabaseMessageSource.loadTexts(DatabaseMessageSource.java:114)
at com.sprsec.init.DatabaseMessageSource.refreshProperties(DatabaseMessageSource.java:90)
at com.sprsec.init.DatabaseMessageSource.reload(DatabaseMessageSource.java:132)
at com.sprsec.init.DatabaseMessageSource.<init>(DatabaseMessageSource.java:35)
at com.sprsec.init.WebAppConfig.getMesageSource(WebAppConfig.java:90)
at com.sprsec.init.WebAppConfig$$EnhancerByCGLIB$$f4b941bb.CGLIB$getMesageSource$3(<generated>)
at com.sprsec.init.WebAppConfig$$EnhancerByCGLIB$$f4b941bb$$FastClassByCGLIB$$c1655200.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:286)
at com.sprsec.init.WebAppConfig$$EnhancerByCGLIB$$f4b941bb.getMesageSource(<generated>)
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.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:160)
... 57 more
DatabaseMessageSource.java:
public class DatabaseMessageSource extends AbstractMessageSource implements MessageSource {
private final Map<String, Map<String, String>> properties = new HashMap<String, Map<String, String>>();
#Autowired
private SessionFactory sessionFactory;
public DatabaseMessageSource() {
super();
//this.sessionFactory = sessionFactory;
this.setUseCodeAsDefaultMessage(true);
reload();
setParentMessageSource(this);
}
/**
* {#inheritDoc}
*/
#Override
protected String resolveCodeWithoutArguments(String code, Locale locale) {
return getText(code, locale);
}
/**
* {#inheritDoc}
*/
#Override
protected MessageFormat resolveCode(String code, Locale locale) {
String msg = getText(code, locale);
MessageFormat result = createMessageFormat(msg, locale);
return result;
}
/**
* #param code
* #param locale
* #return
*/
private String getText(String code, Locale locale) {
Map<String, String> localizedText = properties.get(locale.getLanguage());
System.out.println("===================================================");
System.out.println("requested code: "+code+" Result: "+localizedText.get(code));
System.out.println("===================================================");
String textForCurrentLanguage = null;
if (localizedText != null) {
textForCurrentLanguage = localizedText.get(code);
if (textForCurrentLanguage == null) {
saveKeyword(code);
reload();
return "__"+code;
}else if (textForCurrentLanguage.equals("")){
return "__"+code;
} else {
return textForCurrentLanguage;
}
} else {
return "__"+code;
}
}
/**
* #return properties which keeps localized text
*/
private Map<String, Map<String, String>> refreshProperties() {
properties.clear();
properties.putAll(loadTexts());
return properties;
}
public Session openSession(){
return sessionFactory.openSession();
}
private void saveKeyword(final String key){
Query query = openSession().createSQLQuery("insert into b_dictionary (keyword,lang_ru,lang_lv,lang_en) values ('"+key+"','','','')");
query.executeUpdate();
}
private Iterator getSQLDictionary(){
Query query = openSession().createSQLQuery("select m.keyword, m.lang_ru, m.lang_lv, m.lang_en from b_dictionary as m");
return query.list().iterator();
}
protected Map<String, Map<String, String>> loadTexts() {
Map<String, Map<String, String>> myProp = new HashMap<String, Map<String, String>>();
Map<String, String> dataRU = new HashMap<String, String>();
Map<String, String> dataLV = new HashMap<String, String>();
Map<String, String> dataEN = new HashMap<String, String>();
Iterator result = getSQLDictionary();
while( result.hasNext() ){
Object[] row = (Object[]) result.next();
String code = row[0].toString();
dataRU.put(code,row[1].toString());
dataLV.put(code,row[2].toString());
dataEN.put(code,row[3].toString());
}
myProp.put("ru", dataRU);
myProp.put("lv", dataLV);
myProp.put("en", dataEN);
return myProp;
}
/**
* Reload all codes.
*/
public void reload() {
refreshProperties();
}
}
Your problem is here:
new DatabaseMessageSource(sessionFactory().getObject());
Spring can only autowire beans that it manages; if you call new to create a bean yourself, #Autowired fields don't get filled in (and methods like #PostConstruct aren't called). The field should get filled in after it gets returned by the #Bean method, but if you need to access it in the bean's constructor, you'll have to pass it in as a parameter. The preferred solution is to move the code that relies on the #Autowired setup into a method annotated with #PostConstruct.
Try AnnotationSessionFactoryBean instead of LocalSessionFactoryBean
LocalSessionFactoryBean sessionFactoryBean = new AnnotationSessionFactoryBean();
Related
I have a java project with spring framework. I have 4.3.12 (not spring boot!).
My repositories are interfaces, extended from spring base Repository interface.
I have implemented many unit tests with in-memory repositories, however in the database (postgreslq) I have some real database functions, which I would like to test. I cannot implement those with JPA queries.
Now I want to test those database functions, so I want to make integration test. However when the application context is initializing, i cannot load the repository interfaces, and receiving
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'com.company.model.UserRepository' available:
expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
exception.
Test class
#RunWith(SpringRunner.class)
#ContextConfiguration(classes = { ApplicationContext.class })
public class UserControllerIntegrationTest {
#Autowired
private UserRepository userRepository;
.. test methods
}
The ApplicationContext.class is the real #Configuration class in the project. And it loads the datasource, entitymanagerfactory, transactionmanager, etc. when I execute the test.
package com.company.config;
import com.company.service.email.EmailService;
import com.zaxxer.hikari.HikariDataSource;
import java.util.Properties;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.flywaydb.core.Flyway;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.core.env.Environment;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#PropertySources({
#PropertySource("classpath:application.properties"),
#PropertySource("file:${CCTNG_HOME}/application.properties")
})
#ComponentScan({"com.company"})
#EnableWebMvc
#EnableTransactionManagement
public class ApplicationContext {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_DATABASE_MIGRATE_USERNAME = "db.migrate.username";
private static final String PROPERTY_NAME_DATABASE_MIGRATE_PASSWORD = "db.migrate.password";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
private static final String PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY = "hibernate.ejb.naming_strategy";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_HIBERNATE_DDL_AUTO = "hibernate.hbm2ddl.auto";
// private static final String PROPERTY_NAME_HIBERNATE_IMPORT_FILES = "hibernate.hbm2ddl.import_files";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
private static final String PROPERTY_NAME_LDAP_URL = "ldap.url";
private static final String PROPERTY_NAME_LDAP_USERNAME = "ldap.principal";
private static final String PROPERTY_NAME_LDAP_PASSWORD = "ldap.password";
private static final String PROPERTY_NAME_EMAIL_USERNAME = "email.username";
private static final String PROPERTY_NAME_EMAIL_APPPASSWORD = "email.apppassword";
#Resource
private Environment environment;
#Bean(initMethod = "migrate")
public Flyway flyway() {
Flyway flyway = new Flyway();
// flyway.setBaselineOnMigrate(true);
// flyway.setDataSource(dataSource());
flyway.setDataSource(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_URL), environment.getRequiredProperty(PROPERTY_NAME_DATABASE_MIGRATE_USERNAME),
environment.getRequiredProperty(PROPERTY_NAME_DATABASE_MIGRATE_PASSWORD), new String[]{});
return flyway;
}
// #Value("classpath:schema-postgresql.sql")
// private org.springframework.core.io.Resource schemaScript;
#Bean
public DataSource dataSource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setJdbcUrl(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
#Bean
public PlatformTransactionManager transactionManager() throws ClassNotFoundException {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
return transactionManager;
}
#Bean(name = "entityManagerFactory")
#DependsOn("flyway")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() throws ClassNotFoundException {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPackagesToScan(environment.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
Properties jpaProterties = new Properties();
jpaProterties.put(PROPERTY_NAME_HIBERNATE_DIALECT, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
jpaProterties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
jpaProterties.put(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY));
jpaProterties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
jpaProterties.put(PROPERTY_NAME_HIBERNATE_DDL_AUTO, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DDL_AUTO));
// jpaProterties.put(PROPERTY_NAME_HIBERNATE_IMPORT_FILES, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_IMPORT_FILES));
// jpaProterties.put("spring.jpa.properties.hibernate.jdbc.batch_size", "25");
// jpaProterties.put("spring.jpa.properties.hibernate.order_inserts", "true");
// jpaProterties.put("spring.jpa.properties.hibernate.order_updates", "true");
// jpaProterties.put("spring.jpa.properties.hibernate.generate_statistics", "true");
entityManagerFactoryBean.setJpaProperties(jpaProterties);
return entityManagerFactoryBean;
}
#Bean
public LdapContextSource ldapContextSource() {
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl(environment.getRequiredProperty(PROPERTY_NAME_LDAP_URL));
contextSource.setUserDn(environment.getRequiredProperty(PROPERTY_NAME_LDAP_USERNAME));
contextSource.setPassword(environment.getRequiredProperty(PROPERTY_NAME_LDAP_PASSWORD));
return contextSource;
}
#Bean
public LdapTemplate ldapTemplate() {
return new LdapTemplate(ldapContextSource());
}
#Bean(name = "emailService")
public EmailService email() {
Properties props = new Properties();
props.put("mail.smtp.host", "mailrelay.xxx.com");
props.put("mail.smtp.port", "25");
props.put("mail.smtp.auth", "false");
props.put("mail.smtp.connectiontimeout", "10000");
EmailService email = new EmailService(
environment.getRequiredProperty(PROPERTY_NAME_EMAIL_USERNAME),
environment.getRequiredProperty(PROPERTY_NAME_EMAIL_APPPASSWORD),
// environment.getRequiredProperty(PROPERTY_NAME_EMAIL_APPROOT),
props);
return email;
}
}
But for some reason the repositories are not initiated.
Thanks for any hint!
I am using the version of SpringBooot 1.8. Using #Cacheable annotations in the Service layer does not cache the data. Through debugging, it is found that some of the Service objects in the Controller layer are proxied by cglib, but some of them are not. The wordings are similar in nature. Why does this happen and how should it be solved ?
ApplicationBoot:
#SpringBootApplication
#EnableCaching
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
}
Service:
#Service
#Slf4j
public class MovieServiceImpl extends ServiceImpl<MovieMapper,Movie> implements MovieService {
#Resource
private PlayService playService;
#Resource
private DownloadService downloadService;
#Resource
private PlayApiService playApiService;
#Resource
private AreaService areaService;
#Resource
private CategoryService categoryService;
#Resource
private IncrementRecordsService inService;
#Override
#Cacheable(value = "nowIsAndFuck")
public Movie nowIsAndFuck() {
log.debug("movie-test 执行查询:"+1);
return this.selectById(1);
}
}
Cache Config:
package com.aikanyingshi.web.core.config.cache;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
#Configuration
#Component
public class RedisConfig extends CachingConfigurerSupport {
#Resource
private RedisConfigProperties redisConfigProperties;
#Bean
public RedisConnectionFactory redisConnectionFactory(){
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(redisConfigProperties.getHost());
factory.setPort(redisConfigProperties.getPort());
if(redisConfigProperties.getPassword()!=null){
factory.setPassword(redisConfigProperties.getPassword());
}
return factory;
}
#Bean
public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<String,String> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.afterPropertiesSet();
setSerializer(template);
return template;
}
#Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
cacheManager.setDefaultExpiration(10);
return cacheManager;
}
private void setSerializer(RedisTemplate<String, String> template) {
Jackson2JsonRedisSerializer serializer
= new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(om);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
}
#Override
public KeyGenerator keyGenerator() {
return (o, method, objects) -> {
StringBuilder sb = new StringBuilder();
sb.append(o.getClass().getName());
sb.append(":");
sb.append(method);
for (Object object : objects) {
sb.append(":");
sb.append(object.toString());
}
return sb.toString();
};
}
}
I recently started working on springBoot projects.
I wrote a sample program where I am fetching data from the DB, modifying it and storing it back in the DB.
The problem I am facing is, I am able to get the data from the DB but when saving it back, I am getting the below exception.
org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is
javax.persistence.TransactionRequiredException: no transaction is in progress at
org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:413) at
org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246)
Below is my Code.
DataConfiguraiton.java
import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
*
* This class contains code to configure database.
* #author satish
*
*/
#Configuration
#EntityScan(basePackages= {"com.tushar.common.model"})
#ComponentScan(basePackages= {"com.tushar.common.model"})
#EnableJpaRepositories(basePackages={"com"})
#EnableTransactionManagement
public class DataConfiguration {
#Value("${spring.datasource.driver-class-name}")
private String driverClassName;
#Value("${spring.datasource.url}")
private String url;
#Value("${spring.datasource.username}")
private String username;
#Value("${spring.datasource.password}")
private String password;
#Value("${spring.datasource.dialect}")
private String dialect;
/**
*
* It will scan the package where our entities appears.
* #param dataSource
* #return
*/
#Bean
#Autowired
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
Properties jpaProperties = new Properties();
jpaProperties.setProperty("hibernate.show_sql", "true");
jpaProperties.setProperty("hibernate.dialect", dialect);
jpaProperties.setProperty("hibernate.hbm2ddl.auto", "update");
LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean =
new LocalContainerEntityManagerFactoryBean();
localContainerEntityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
localContainerEntityManagerFactoryBean.setPackagesToScan(new String[] {"com.att.pricerd.discountmanagement.model"});
localContainerEntityManagerFactoryBean.setDataSource(dataSource);
localContainerEntityManagerFactoryBean.setJpaProperties(jpaProperties);
return localContainerEntityManagerFactoryBean;
}
/**
*
* It will set the database properties to the data Source.
* #return
*/
#Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
#Bean
#Autowired
public JpaTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean emf) throws Exception {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf.getObject());
transactionManager.setEntityManagerFactory(emf.getNativeEntityManagerFactory());
return transactionManager;
}
}
Repository
#Repository
public interface EmployeeRepository extends JpaRepository<Employee,Long> {
}
DAO Class
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Component
public class EmployeeDataManagementDaoImpl implements EmployeeDataManagementDao {
private static final Logger LOG = LoggerFactory.getLogger(EmployeeDataManagementDaoImpl.class);
#Autowired
private EmployeeDataManagmentUtil EmployeeDataManagmentUtil;
#Autowired
private SalesEmployeesRepository salesEmployeesRepository;
#Autowired
private EmployeeRepository employeeRepository;
#PersistenceContext
private EntityManager em;
#Override
public void addEmployee(EmployeeDetailsRequestVo EmployeeRequest) {
convertAndSaveSalesEmployee(EmployeeRequest);
}
/**
* Fetch data from DB, update the inital and maximum Employee and
* save it back to DB.
* #throws DataNotFoundException
*
*/
#Override
public void changeEmployee(List<Employee> Employees) throws EmployeeManagementException {
for (Employee employee : Employees) {
List<Employee> EmployeesDB;
try {
EmployeesDB = getEmployeeFromDB(employee);
} catch (DataNotFoundException e) {
List<String> errorMessage = new ArrayList<>();
errorMessage.add(e.getMessage());
LOG.error(e.getMessage(),e);
throw new EmployeeManagementException(errorMessage);
}
for (Employee employee : EmployeesDB) {
if (employee.getMaxEmployee() != null) {
Employee.setMaxEmployee(employee.getMaxEmployee());
}
if (employee.getInitialEmployee() != null) {
Employee.setInitialEmployee(employee.getInitialEmployee());
}
employeeRepository.saveAndFlush(Employee);
}
}
}
/**
* This method is used to get the Employee details from DB.
*
* #param employee
* #return List<Employee>
* #throws DataNotFoundException
*/
private List<Employee> getEmployeeFromDB(Employee employee)
throws DataNotFoundException {
List<Employee> EmployeesDB = findByAllEmployeesFilters(employee.getempId(),
employee.getyearsExp(), employee.getdeptLevInd(), employee.getsalary(),
employee.getaddress(), employee.getCountryCd(), employee.getpinCode());
if (EmployeesDB.isEmpty()) {
String errCode = ""; // error code for data not found, yet to be
// decided.
LOG.error("ERROR CODE :: {}", errCode);
throw new DataNotFoundException(errCode);
}
return EmployeesDB;
}
/**
* This method will update the end date Employee
* #param List<Employee>
*/
#Override
public void inactivateEmployee(List<Employee> Employees)
throws EmployeeManagementException {
for (Employee employee : Employees) {
List<Employee> employeesDB;
try {
employeesDB = getEmployeeFromDB(employee);
} catch (DataNotFoundException e) {
List<String> errorMessage = new ArrayList<>();
errorMessage.add(e.getMessage());
LOG.error(e.getMessage(),e);
throw new EmployeeManagementException(errorMessage);
}
for (Employee employee : EmployeesDB) {
if (employee.getEmployeeEndDate() != null) {
employee.setEmployeeEndDate(employee.getEmployeeEndDate());
}
//
employeeRepository.saveAndFlush(Employee);
}
}
}
/**
*
* #param empId
* #param yearsExp
* #param bigDecimal
* #param salary
* #param regionId
* #param countryCd
* #param pinCode
* #return
*/
private List<Employee> findByAllEmployeeFilters(BigDecimal empId, BigDecimal yearsExp,
BigDecimal bigDecimal, BigDecimal salary, String regionId, String countryCd, String pinCode) {
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> criteriaQuery = criteriaBuilder
.createQuery(Employee.class);
Root<Employee> root = criteriaQuery.from(Employee.class);
criteriaQuery.where(criteriaBuilder.equal(root.get("empId"), empId),
criteriaBuilder.equal(root.get("deptLevInd"), bigDecimal),
criteriaBuilder.equal(root.get("yearsExp"), yearsExp), criteriaBuilder.equal(root.get("salary"), salary),
criteriaBuilder.equal(root.get("address"), regionId),
criteriaBuilder.equal(root.get("countryCd"), countryCd),
criteriaBuilder.equal(root.get("pinCode"), pinCode));
return em.createQuery(criteriaQuery).getResultList();
}
}
The getEmployeeFromDB gets me the values from DB but saveAndFlush is giving me the exception.
Actualy Bedla is rigth, you should use #Transactional. What i want to add that method changeEmployee should be declared in Service class. Correct desing is create EmployeeService class and move method changeEmployee to it, and annotate service with #Transactional. Generaly dao should contain only find methods to load from db and update/save methods to save.
Since I am new to Spring and i have an issue with user service. I have admin panel and customer blog. When the Customer is logged into browser, the admin has been changed the status to Active from InActive in Table of Customer. But the user session is active. So that he can able to do process after the status is changed.
I need one common method that should be in common place. This method should be access the table and validate the user per every request. I have one controller and that should invoke the common method. Because I cannot edit code to every class. In JSP & Servlet I have handled this using doFilter. How to achieve this in Spring..
AppInitializer.java
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
registration.setMultipartConfig(getMultipartConfigElement());
}
private MultipartConfigElement getMultipartConfigElement() {
MultipartConfigElement multipartConfigElement = new MultipartConfigElement( LOCATION, MAX_FILE_SIZE, MAX_REQUEST_SIZE, FILE_SIZE_THRESHOLD);
return multipartConfigElement;
}
private static final String LOCATION = "C:/temp/"; // Temporary location where files will be stored
private static final long MAX_FILE_SIZE = 5242880; // 5MB : Max file size.
// Beyond that size spring will throw exception.
private static final long MAX_REQUEST_SIZE = 20971520; // 20MB : Total request size containing Multi part.
private static final int FILE_SIZE_THRESHOLD = 0;
}
AppConfig.java
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
registration.setMultipartConfig(getMultipartConfigElement());
}
private MultipartConfigElement getMultipartConfigElement() {
MultipartConfigElement multipartConfigElement = new MultipartConfigElement( LOCATION, MAX_FILE_SIZE, MAX_REQUEST_SIZE, FILE_SIZE_THRESHOLD);
return multipartConfigElement;
}
private static final String LOCATION = "C:/temp/"; // Temporary location where files will be stored
private static final long MAX_FILE_SIZE = 5242880; // 5MB : Max file size.
// Beyond that size spring will throw exception.
private static final long MAX_REQUEST_SIZE = 20971520; // 20MB : Total request size containing Multi part.
private static final int FILE_SIZE_THRESHOLD = 0;
}
HibernateConfiguration.java
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
#ComponentScan({ "com.ppts.configuration" })
#PropertySource(value = { "classpath:application.properties" })
public class HibernateConfiguration {
#Autowired
private Environment environment;
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "com.ppts.model" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
return properties;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(s);
return txManager;
}
}
AppController.java
package com.sample.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.FileCopyUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.multipart.MultipartFile;
import com.sample.handler.FileHandler;
import com.sample.model.Address;
import com.sample.model.Employee;
import com.sample.model.EmployeeDocument;
import com.sample.model.EmployeeSalary;
import com.sample.model.FileBucket;
import com.sample.model.User;
import com.sample.model.UserProfile;
import com.sample.service.EmployeeDocumentService;
import com.sample.service.EmployeeSalaryService;
import com.sample.service.EmployeeService;
import com.sample.service.UserProfileService;
import com.sample.service.UserService;
import com.sample.validators.FileValidator;
#Controller
#RequestMapping("/")
#SessionAttributes("roles")
public class AppController {
#Autowired
UserService userService;
#Autowired
EmployeeService employeeService;
#Autowired
EmployeeSalaryService employeeSalaryService;
#Autowired
UserProfileService userProfileService;
#Autowired
EmployeeDocumentService employeeDocumentService;
#Autowired
FileValidator fileValidator;
#InitBinder("fileBucket")
protected void initBinderFileBucket(WebDataBinder binder) {
binder.setValidator(fileValidator);
}
#Autowired
MessageSource messageSource;
#Autowired
PersistentTokenBasedRememberMeServices persistentTokenBasedRememberMeServices;
#Autowired
AuthenticationTrustResolver authenticationTrustResolver;
#RequestMapping(value = { "/", "/list" }, method = RequestMethod.GET)
public String adminPage(ModelMap model) {
model.addAttribute("home",true);
model.addAttribute("loggedinuser", getPrincipal());
return "home";
}
#RequestMapping(value = { "/userList" }, method = RequestMethod.GET)
public String listUsers(ModelMap model) {
List<User> users = userService.findAllUsers();
model.addAttribute("users", users);
model.addAttribute("loggedinuser", getPrincipal());
return "userslist";
}
#RequestMapping(value = { "/newuser" }, method = RequestMethod.GET)
public String newUser(ModelMap model) {
User user = new User();
model.addAttribute("user", user);
model.addAttribute("edit", false);
model.addAttribute("loggedinuser", getPrincipal());
return "registration";
}
#RequestMapping(value = { "/newuser" }, method = RequestMethod.POST)
public String saveUser(#Valid User user, BindingResult result,
ModelMap model) {
if (result.hasErrors()) {
return "registration";
}
if(!userService.isUserSSOUnique(user.getId(), user.getSsoId())){
FieldError ssoError =new FieldError("user","ssoId",messageSource.getMessage("non.unique.ssoId", new String[]{user.getSsoId()}, Locale.getDefault()));
result.addError(ssoError);
return "registration";
}
userService.saveUser(user);
model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " registered successfully");
model.addAttribute("loggedinuser", getPrincipal());
return "registrationsuccess";
}
#RequestMapping(value = { "/edit-user-{ssoId}" }, method = RequestMethod.GET)
public String editUser(#PathVariable String ssoId, ModelMap model) {
User user = userService.findBySSO(ssoId);
model.addAttribute("user", user);
model.addAttribute("edit", true);
model.addAttribute("loggedinuser", getPrincipal());
return "registration";
}
#RequestMapping(value = { "/edit-user-{ssoId}" }, method = RequestMethod.POST)
public String updateUser(#Valid User user, BindingResult result,
ModelMap model, #PathVariable String ssoId) {
if (result.hasErrors()) {
return "registration";
}
userService.updateUser(user);
model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " updated successfully");
model.addAttribute("loggedinuser", getPrincipal());
return "registrationsuccess";
}
//Update User and Employee By Id
#RequestMapping(value = { "/getUserById" }, method = RequestMethod.GET)
public String getUserSSOId(ModelMap model) {
User user = new User();
model.addAttribute("user", user);
model.addAttribute("edit", true);
model.addAttribute("loggedinuser", getPrincipal());
return "userview";
}
#RequestMapping(value = { "/updateByUserId" }, method = RequestMethod.GET)
public String getByUserId( #ModelAttribute User userDetails,ModelMap model,BindingResult result) {
User user =userService.findBySSO(userDetails.getSsoId());
if(user!=null){
model.addAttribute("user", user);
model.addAttribute("edit", true);
model.addAttribute("loggedinuser", getPrincipal());
return "registration";
}else{
FieldError referenceIdError =new FieldError("user","ssoId",messageSource.getMessage("non.empty.userid.notexist", new String[]{userDetails.getSsoId()}, Locale.getDefault()));
result.addError(referenceIdError);
model.addAttribute("loggedinuser", getPrincipal());
return "userview";
}
}
#RequestMapping(value = { "/updateByUserId" }, method = RequestMethod.POST)
public String updateUserById(#Valid User user, BindingResult result,
ModelMap model) {
if (result.hasErrors()) {
return "registration";
}
userService.updateUser(user);
model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " updated successfully");
model.addAttribute("loggedinuser", getPrincipal());
return "registrationsuccess";
}
#RequestMapping(value = { "/deleteByUserId" }, method = RequestMethod.GET)
public String deleteUserById(ModelMap model) {
User user = new User();
model.addAttribute("user", user);
model.addAttribute("delete", true);
model.addAttribute("loggedinuser", getPrincipal());
return "userview";
}
#RequestMapping(value = { "/deleteUserById" }, method = RequestMethod.GET)
public String deleteByuserId( #ModelAttribute User userDetails,ModelMap model,BindingResult result) {
User user=userService.findBySSO(userDetails.getSsoId());
if(user!=null){
userService.deleteUserBySSO(userDetails.getSsoId());
model.addAttribute("loggedinuser", getPrincipal());
model.addAttribute("employeeSuccess", "Employee " + user.getFirstName() + " deleted successfully");
return "registrationsuccess";
}else{
FieldError referenceIdError =new FieldError("employee","employeeReferenceId",messageSource.getMessage("non.empty.userid.notexist", new String[]{userDetails.getSsoId()}, Locale.getDefault()));
model.addAttribute("loggedinuser", getPrincipal());
result.addError(referenceIdError);
return "userview";
}
}
}
You can make create a class implementing Spring's HandlerInterceptor interface. Its preHandle method will be called for every request before request is processed by the Controller method.
Since you just want to process validation check for each request before it is handled, you can create a class extending the HandlerInterceptorAdapter class which provides convenient defaults for all methods in the HandlerInterceptor interface.
You only need to provide implementation as per your business rule for the following method
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
Sample code below
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class TransactionInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// Your business logic goes here
// return true or false depending on whether you want the controller to handle the request or terminate request processing.
}
}
You would need to register the interceptor in Spring Config as below
#EnableWebMvc
#Configuration
public class AppConfig extends WebMvcConfigurerAdapter {
.....
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new YourNewInterceptor());
}
.....
}
You can do that also in Filter. You just have to annotate it with #Component and voila. It becomes a Spring bean. Like this:
#Component
public class UserFilter implements Filter{
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
User user = (User)request.getAttribute("user");
// Do whatever you want with your user
}
#Override
public void destroy() {
}
}
Whenever I try to get SpringMVC's ApplicationContext, a NullPointerException is thrown.
This is my userDao:
package com.markor.smarthome.dao;
import com.markor.smarthome.entities.Users;
import com.markor.smarthome.utilites.SpringContextUtil;
import com.markor.smarthome.utilites.StringUtilty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.HashMap;
import java.util.Map;
/**
* Created by litongjie on 2015/5/12.
*/
public class UserDao {
private JdbcTemplate jdbcTemplate = (JdbcTemplate) SpringContextUtil.getBeans("jdbcTemplate");
private String isExistSql = "SELECT * FROM users WHERE user_id=?";
private String addUserSql = "INSERT INTO users(`user_id`,`password`,`name`,`email`,`note`)VALUES(?,?,?,?,?)";
public boolean isExist(String userID) {
Users user = jdbcTemplate.queryForObject(isExistSql, Users.class, userID);
//如果为空 返回false不存在
if (StringUtilty.isNullOrEmpty(user.getUser_id())) {
return false;
} else return true;
}
public int AddUser(Users user) {
System.out.println("begen");
Map<String, Object> map = new HashMap<>();
map.put("user_id", user.getUser_id());
map.put("password", user.getPassword());
map.put("name", user.getName());
map.put("email", user.getEmail());
map.put("note", user.getNote());
int i = jdbcTemplate.update(addUserSql, map);
return i;
}
public static void main(String[] args) {
System.out.println("main begin");
Users users = new Users();
users.setUser_id("123");
users.setName("LI");
users.setNote("444");
System.out.println("user end"+users);
UserDao userDao = new UserDao();
System.out.print(userDao.AddUser(users));
}
}
This is my SpringContextUtil
package com.markor.smarthome.utilites;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletContext;
/**
* 获取Spring上下文及国际化
*
* #author bingchuan -->www.vijun.com
*/
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext application = null;
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.application = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return application;
}
public static Object getBeans(String beanname) {
ApplicationContext applicationContext = getApplicationContext();
return applicationContext.getBean(beanname);
}
I tried using some other's answers, but it didn't work either. Here is my exception:
Exception in thread "main" java.lang.NullPointerException
at com.markor.smarthome.utilites.SpringContextUtil.getBeans(SpringContextUtil.java: 31)
at com.markor.smarthome.dao.UserDao.(UserDao.java:18)
at com.markor.smarthome.dao.UserDao.main(UserDao.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
That looks completely wrong. Where did you start up your spring context?
If you want to use it somewhere in the main() method, you have to write something like this:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/application-context.xml");
(but in that case you don't need SpringContextUtil, because you already have your context).
But why don't you add UserDao to the context and let spring inject jdbcTemplate bean into it?
something like this:
UserDao:
public class UserDao {
#Autowire
private JdbcTemplate jdbcTemplate;
.....
spring context:
<bean id="jdbcTemplate" class=.../>
<bean id="userDao" class="com.markor.smarthome.dao.UserDao"/>