package com.batch.hibernate.config;
import javax.sql.DataSource;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.step.skip.SkipPolicy;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.LineMapper;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.batch.item.file.transform.LineTokenizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.FileSystemResource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import com.batch.hibernate.job.FileVerificationSkipper;
import com.batch.hibernate.job.UserItemPreparedStatementSetter;
import com.batch.hibernate.job.UserItemProcessor;
import com.batch.hibernate.model.User;
#Configuration
#EnableBatchProcessing
/*#ComponentScan(basePackages = { "com.batch.hibernate" })
#PropertySource("classpath:application.properties")*/
public class BatchConfiguration {
#Autowired
private Environment environment;
#Autowired
public JobBuilderFactory jobBuilderFactory;
#Autowired
public StepBuilderFactory stepBuilderFactory;
#Autowired
public DataSource dataSource;
#Bean
public DataSource dataSource(){
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getProperty("connection.driver_class"));
dataSource.setUrl(environment.getProperty("connection.url"));
dataSource.setUsername(environment.getProperty("connection.username"));
dataSource.setPassword(environment.getProperty("connection.password"));
return dataSource;
}
#Bean
public FlatFileItemReader<User> reader(){
FlatFileItemReader<User> reader = new FlatFileItemReader<User>();
reader.setResource(new FileSystemResource(environment.getProperty("local.filesystem.path")));
reader.setLinesToSkip(Integer.valueOf(environment.getProperty("header.lines.in.file")));
LineMapper<User> userLineMapper = createUserLineMapper();
reader.setLineMapper(userLineMapper);
return reader;
}
private LineMapper<User> createUserLineMapper() {
DefaultLineMapper<User> userLineMapper = new DefaultLineMapper<>();
LineTokenizer userLineTokenizer = createUserLineTokenizer();
userLineMapper.setLineTokenizer(userLineTokenizer);
FieldSetMapper<User> userInformationMapper = createUserInformationMapper();
userLineMapper.setFieldSetMapper(userInformationMapper);
return userLineMapper;
}
private LineTokenizer createUserLineTokenizer() {
DelimitedLineTokenizer userLineTokenizer = new DelimitedLineTokenizer();
userLineTokenizer.setDelimiter(environment.getProperty("column.delimiter"));
userLineTokenizer.setNames(environment.getProperty("column.names").split(","));
return userLineTokenizer;
}
private FieldSetMapper<User> createUserInformationMapper() {
BeanWrapperFieldSetMapper<User> userInformationMapper = new BeanWrapperFieldSetMapper<>();
userInformationMapper.setTargetType(User.class);
return userInformationMapper;
}
#Bean
public UserItemProcessor processor(){
return new UserItemProcessor();
}
#Bean
public JdbcBatchItemWriter<User> writer(){
JdbcBatchItemWriter<User> writer = new JdbcBatchItemWriter<User>();
writer.setDataSource(dataSource);
writer.setSql("INSERT INTO user (name, id) VALUES (?,?)");
writer.setItemPreparedStatementSetter(new UserItemPreparedStatementSetter());
return writer;
}
#Bean
public Step step1(){
return stepBuilderFactory.get("step1")
.<User, User> chunk(10000)
.reader(reader())
.faultTolerant()
.skipPolicy(fileVerificationSkipper())
.processor(processor())
.writer(writer())
.build();
}
#Bean
public Job importUserJob(){
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.flow(step1())
.end()
.build();
}
#Bean
public SkipPolicy fileVerificationSkipper() {
return new FileVerificationSkipper();
}
/*#Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}*/
}
and my HibernateUtil.java is:
package com.batch.hibernate.util;
import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import com.batch.hibernate.model.User;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SpringBatchUtil springBatchUtil;
private static Properties properties;
public static SessionFactory buildSessionFactory() {
SessionFactory localSessionFactory = null;
springBatchUtil = new SpringBatchUtil();
try {
Configuration configuration = new Configuration();
properties = springBatchUtil.loadProperties();
configuration.setProperty(SpringBatchConstants.HIBERNATE_CONNECTION_URL,
properties.getProperty(SpringBatchConstants.HIBERNATE_CONNECTION_URL));
configuration.setProperty(SpringBatchConstants.HIBERNATE_CONNECTION_USERNAME,
properties.getProperty(SpringBatchConstants.HIBERNATE_CONNECTION_USERNAME));
configuration.setProperty(SpringBatchConstants.HIBERNATE_CONNECTION_PASSWORD,
properties.getProperty(SpringBatchConstants.HIBERNATE_CONNECTION_PASSWORD));
configuration.setProperty(SpringBatchConstants.HIBERNATE_SHOW_SQL,
properties.getProperty(SpringBatchConstants.HIBERNATE_SHOW_SQL));
configuration.setProperty(SpringBatchConstants.HIBERNATE_CURRENT_SESSION_CONTEXT_CLASS,
properties.getProperty(SpringBatchConstants.HIBERNATE_CURRENT_SESSION_CONTEXT_CLASS));
configuration.setProperty(SpringBatchConstants.HIBERNATE_CONNECTION_DRIVER_CLASS,
properties.getProperty(SpringBatchConstants.HIBERNATE_CONNECTION_DRIVER_CLASS));
configuration.addPackage("com.batch.hibernate.model");
configuration.addAnnotatedClass(User.class);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
localSessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (HibernateException he) {
he.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return localSessionFactory;
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static Session getSession() throws Exception {
if (getSessionFactory() == null) {
throw new HibernateException("Initial SessionFactory creation failed.");
}
Session session = getSessionFactory().getCurrentSession();
session.getTransaction().begin();
return session;
}
public static void closeSession(Session session) {
if (session != null) {
if (session.getTransaction().isActive()) {
session.getTransaction().commit();
}
session.close();
}
}
}
I have dataSource settings and hibernateUtil as above, I want to use hibernate rather than JDBC while configuring dataSource.
The prime reason to integrate with hibernate is for auditing purpose while writing records from file to database.
How can I use hibernate here in this context? or Is there a way to audit using the way I am already using?
Sorry if i am not clear with my question.
Have a look at Spring-starter-data-jpa. Set the needed properties like hibernate.dialect etc, and you don't need to do anything yourself, it works o.o.t.b.
Spring data jpa should be enough to solve all your issues.
Please look at this Repo for starter guide .
https://github.com/rahulrsingh09/Spring-Boot-DataJPA
Related
Like tittle says I Have two DataSource in my application and the first repository is work fine , but my second repository can't save update or delete only query works good . when i check the console there is no error appear . Can some one help?
first repository config
package com.iisigroup.product.insightplatform.config;
import com.iisigroup.product.insightplatform.repository.jpa.CustomMsgRutLogsRepository;
import com.iisigroup.product.insightplatform.repository.jpa.impl.BaseRepositoryImpl;
import com.iisigroup.product.insightplatform.repository.jpa.impl.MsgRutLogsGeneralRepositoryImpl;
import com.iisigroup.product.insightplatform.repository.jpa.impl.MsgRutLogsOracleRepositoryImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = "com.iisigroup.product.insightplatform.repository.jpa"
, repositoryBaseClass = BaseRepositoryImpl.class,
transactionManagerRef = "JPATra", entityManagerFactoryRef = "entityManagerFactory1")
public class JPAConfig {
#Autowired
private DataSource dataSource;
#Autowired
private Environment env;
#Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource);
}
#Primary
#Bean(name = "JPATra")
public PlatformTransactionManager transactionManager1() {
final JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory1());
return txManager;
}
#Bean(name = "entityManagerFactory1")
#Primary
public EntityManagerFactory entityManagerFactory1() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaProperties(hibernateProperties());
em.setJpaVendorAdapter(vendorAdapter);
em.setPackagesToScan(new String[]{"com.iisigroup.product.insightplatform.domain.jpa"});
em.setPersistenceUnitName("emfBW");
em.afterPropertiesSet();
return em.getObject();
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.show_sql", "false");
properties.setProperty("hibernate.max_fetch_depth", "3");
properties.setProperty("hibernate.jdbc.fetch_size", "50");
properties.setProperty("hibernate.jdbc.batch_size",
env.getProperty("spring.jpa.properties.hibernate.jdbc.batch_size"));
properties.setProperty("hibernate.enable_lazy_load_no_trans", "true");
return properties;
}
}
second repository
package com.iisigroup.product.insightplatform.config;
import com.iisigroup.product.insightplatform.repository.traffic.BaseRepositoryImpl;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import java.util.Properties;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = "com.iisigroup.product.insightplatform.repository.traffic",
repositoryBaseClass = BaseRepositoryImpl.class,
entityManagerFactoryRef = "trafficentityManagerFactory",
transactionManagerRef = "traffictransactionManager")
public class TrafficJPAConfig {
#Autowired
private Environment env;
#Bean(name = "trafficDatasource")
public HikariDataSource trafficDatasource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl("secondUrl");
dataSource.setUsername("secondUser");
dataSource.setPassword("secondPass");
dataSource.setMaximumPoolSize(8);
dataSource.setIdleTimeout(15);
dataSource.setConnectionTimeout(3000);
return dataSource;
}
#Bean
public JdbcTemplate trafficjdbcTemplate() {
return new JdbcTemplate(trafficDatasource());
}
#PersistenceContext(unitName="traffic")
#Bean(name = "traffictransactionManager")
public PlatformTransactionManager traffictransactionManager() {
final JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(productEntityManager().getObject());
return txManager;
}
#PersistenceContext(unitName="traffic")
#Bean(name = "trafficentityManagerFactory")
public EntityManagerFactory trafficentityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(trafficDatasource());
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaProperties(hibernateProperties());
em.setJpaVendorAdapter(vendorAdapter);
em.setPackagesToScan(new String[]{"com.iisigroup.product.insightplatform.repository.traffic","com.iisigroup.product.insightplatform.domain.jpa"});
em.setPersistenceUnitName("traffic");
em.afterPropertiesSet();
return em.getObject();
}
#Bean
#PersistenceContext(unitName="traffic")
public LocalContainerEntityManagerFactoryBean productEntityManager() {
final LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
em.setDataSource(trafficDatasource());
em.setPackagesToScan(
new String[] {"com.iisigroup.product.insightplatform.repository.traffic","com.iisigroup.product.insightplatform.domain.jpa"});
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(hibernateProperties());
return em;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.show_sql", "true");
properties.setProperty("hibernate.max_fetch_depth", "3");
properties.setProperty("hibernate.jdbc.fetch_size", "50");
properties.setProperty("hibernate.jdbc.batch_size",
env.getProperty("spring.jpa.properties.hibernate.jdbc.batch_size"));
properties.setProperty("hibernate.enable_lazy_load_no_trans", "true");
return properties;
}
}
And I try to override delete method with under code , it's work great
#Override
public void delete(String s) {
TrafficJPAConfig cc = new TrafficJPAConfig();
JdbcTemplate temp = cc.trafficjdbcTemplate();
String sql = String.format("delete from UserColumnGrpFieldValueSTB where UUID ='%s' ", s);
temp.execute(sql);
// super.delete(s);
}
after using second Data source in isolated environment , it didn't make any difference. But it work after I change my second Data source config like my code below, it works fine. I don't know the reason it work and i'm curious of that, any one knows why?
#Configuration
//#ComponentScan("com.iisigroup.product.insightplatform.domain.jpa")
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = "com.iisigroup.product.insightplatform.repository.traffic",
repositoryBaseClass = BaseRepositoryImpl.class,
entityManagerFactoryRef = "trafficentityManagerFactory",
transactionManagerRef = "traffictransactionManager")
public class TrafficJPAConfig {
#Autowired
private Environment env;
#Bean(name = "trafficDatasource")
public HikariDataSource trafficDatasource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl("secondDatasouce");
dataSource.setUsername("secondDatasouce");
dataSource.setPassword("secondDatasouce");
dataSource.setMaximumPoolSize(8);
dataSource.setIdleTimeout(15);
dataSource.setConnectionTimeout(3000);
return dataSource;
}
#Bean
public JdbcTemplate trafficjdbcTemplate() {
return new JdbcTemplate(trafficDatasource());
}
#PersistenceContext(unitName="traffic")
#Bean(name = "traffictransactionManager")
public PlatformTransactionManager traffictransactionManager() {
final JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(trafficentityManagerFactory());
return txManager;
}
#PersistenceContext(unitName="traffic")
#Bean(name = "trafficentityManagerFactory")
public EntityManagerFactory trafficentityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(trafficDatasource());
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaProperties(hibernateProperties());
em.setJpaVendorAdapter(vendorAdapter);
// em.setEntityManagerFactoryInterface(MultiEntityManagerFactory.class);
em.setPackagesToScan(new String[]{"com.iisigroup.product.insightplatform.repository.traffic","com.iisigroup.product.insightplatform.domain.jpa"});
em.setPersistenceUnitName("traffic");
em.afterPropertiesSet();
return em.getObject();
}
// #Bean
// #PersistenceContext(unitName="traffic")
// public LocalContainerEntityManagerFactoryBean productEntityManager() {
// final LocalContainerEntityManagerFactoryBean em
// = new LocalContainerEntityManagerFactoryBean();
// em.setDataSource(trafficDatasource());
// em.setPackagesToScan(
// new String[] {"com.iisigroup.product.insightplatform.repository.traffic","com.iisigroup.product.insightplatform.domain.jpa"});
// JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
//// final HashMap<String, Object> properties = new HashMap<String, Object>();
//// properties.put("hibernate.hbm2ddl.auto", "auto");
//// properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
//// em.setJpaPropertyMap(properties);
// em.setJpaVendorAdapter(vendorAdapter);
// em.setJpaProperties(hibernateProperties());
//
// return em;
// }
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.show_sql", "true");
properties.setProperty("hibernate.max_fetch_depth", "3");
properties.setProperty("hibernate.jdbc.fetch_size", "50");
properties.setProperty("hibernate.jdbc.batch_size",
env.getProperty("spring.jpa.properties.hibernate.jdbc.batch_size"));
properties.setProperty("hibernate.enable_lazy_load_no_trans", "true");
return properties;
}
}
Good afternoon, I am experiencing an issue where my spring application is not autowiring a Datasource to a DAO. The database is a postgresql db being ran on my local machine. I'm getting a null pointer exception in my userDAO where we try to execute datasource.getConnection, which is the error being caused when a certain endpoint of the api is requested. In the DatabaseConfig class method postgresDatasource, there is a commented out try catch block where I see if we still get thrown a null pointer exception if we attempt ds.getConnection. It does not throw an exception in there, event though that code is being ran at server build. Like I said, the error gets thrown when I assume that the autowiring is being execute corrected and we try datasource.getConnection. All relevant code will be pasted below. first is the DatabaseConfig class. It may be worth noting that my DatabaseConfig is in com.example.config, and the DAO is in com.example.dao
#Configuration
#ComponentScan(basePackages="com.example")
public class DatabaseConfig {
#Bean
public DataSource postgresDataSource() {
final DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("org.postgresql.Driver");
ds.setUrl("jdbc:postgresql://localhost:5432/postgres");
ds.setUsername("username");
ds.setPassword("password");
// System.out.println("Returning ds object after setting parameters");
// System.out.println(ds.toString());
// try {
// System.out.println("Attempting connection at server build.");
// ds.getConnection();
// } catch (SQLException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
System.out.println("DataSource postgresDataSource() is being ran");
return ds;
}
}
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import com.fmn.config.DatabaseConfig;
import com.fmn.dto.UserDTO;
#Repository
public class UserDAO {
// #Autowired
private DataSource datasource;
// #Autowired
// public void setDataSource(DataSource datasource) {
// this.datasource = datasource;
// }
//
#Autowired
public UserDAO(DataSource datasource){
System.out.println("Setting datasource in constructor");
this.datasource = datasource;
}
//
public UserDAO() {};
public boolean addUser(UserDTO user) {
//TODO: implement
return false;
}
public boolean updateUser(UserDTO user) {
//TODO: implement
return false;
}
public UserDTO getUserInfo(UserDTO user)/*throws UserNotFoundException*/ {
//TODO: implement
if(user.getUserId() != null) {
return getUserInfoWithUserID(user);
} else if (user.getEmail() != null) {
return getUserInfoWithEmail(user);
} else if (user.getPhoneNum() != null) {
return getUserInfoWithPhone(user);
}
//else throw new UserNotFoundException();
return null;
}
private UserDTO getUserInfoWithEmail(UserDTO user) {
//TODO: implement
return null;
}
private UserDTO getUserInfoWithPhone(UserDTO user) {
//TODO: implement
return null;
}
public UserDTO getUserInfoWithUserID(UserDTO user) {
UserDTO outUser = null;
ResultSet result = null;
Connection conn = null;
try {
// DatabaseConfig dbc = new DatabaseConfig();
// System.out.println("Setting datasource");
// datasource = dbc.postgresDataSource();
System.out.println("Calling datasource.getConnection()");
conn = datasource.getConnection();
CallableStatement caller = conn.prepareCall("{?= call get_user_info_with_userid(?)}");
caller.registerOutParameter(1, Types.REF_CURSOR);
caller.setString(2, user.getUserId());
caller.execute();
result = caller.getResultSet();
result.next();
outUser = setUserDTOFromResultSet(result);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return outUser;
}
private UserDTO setUserDTOFromResultSet(ResultSet result) throws SQLException {
UserDTO outUser = new UserDTO();
outUser.setDOB(result.getDate("DOB"));
outUser.setUserId(result.getString("USER_ID"));
outUser.setfName(result.getString("F_NAME"));
outUser.setlName(result.getString("L_NAME"));
outUser.setEmail(result.getString("EMAIL"));
outUser.setAliveFlg(result.getString("ALIVE_FLG"));
return outUser;
}
}
#SpringBootApplication
#EnableAutoConfiguration
#ComponentScan(basePackageClasses = {DatabaseConfig.class, InteractiveController.class, UserDAO.class})
public class Application {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(DatabaseConfig.class);
ctx.refresh();
SpringApplication.run(Application.class, args);
}
}
Your feedback and input is appreciated. Thank you!
I'm trying to migrate from Spring XML based configuration to Pure Java Configuration, I have configured all the configuration files, but when I try to enter the username and password in login page, it redirects me back to the login page again. I believe the userServiceImpl method is not being invoked because the control is not going there.
Here, I have autowired userServiceImpl method which is implementing UserDetailsService of spring security core credentials.
package com.lw.sms.config;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.orm.hibernate4.LocalSessionFactoryBuilder;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.lw.sms.CustomAuthenticationSuccessHandler;
import com.lw.sms.UserServiceImpl;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
#EnableTransactionManagement
#Order(1000)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
#Value("${jdbc.dialect}")
String jdbcDialect;
#Value("${jdbc.driverClassName}")
String jdbcDriverClassName;
#Value("${jdbc.databaseurl}")
String jdbcDatabaseurl;
#Value("${jdbc.username}")
String jdbcusername;
#Value("${jdbc.password}")
String jdbcPassword;
#Autowired
private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
#Autowired
private UserServiceImpl userServiceImpl;
#Override
public void configure(final AuthenticationManagerBuilder auth) throws Exception {
logger.info("configure auth");
auth.userDetailsService(userServiceImpl);
}
#Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
#Override
public void configure(HttpSecurity http) throws Exception {
logger.info("configure http");
http.httpBasic().disable();
http.authorizeRequests().and().formLogin().loginPage("/login").usernameParameter("employeeId")
.passwordParameter("password").successHandler(customAuthenticationSuccessHandler)
.failureUrl("/login?error").defaultSuccessUrl("/dashboard", true)
.loginProcessingUrl("j_spring_security_check")
.and().logout().logoutUrl("/j_spring_security_logout").logoutSuccessUrl("/logout")
.invalidateHttpSession(true).deleteCookies("JSESSIONID")
.and().sessionManagement().invalidSessionUrl("/logout").maximumSessions(1)
.maxSessionsPreventsLogin(true).expiredUrl("/logout");
http.csrf().disable();
http.authorizeRequests().anyRequest().authenticated();
}
#Bean
public SessionRegistry sessionRegistry() {
logger.info("sessionRegistry");
return new SessionRegistryImpl();
}
#Bean
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(dataSource());
builder.scanPackages("com.lw.sms").addProperties(hibernateProperties());
return builder.buildSessionFactory();
}
#Bean
public LocalSessionFactoryBean hibernateSessionFactory() {
logger.info("sessionFactory");
org.hibernate.cfg.Configuration configuration = new org.hibernate.cfg.Configuration();
configuration.configure("hibernate.cfg.xml");
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("com.lw.sms");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public DataSource dataSource() {
logger.info("dataSource");
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(jdbcDriverClassName);
dataSource.setUrl(jdbcDatabaseurl);
dataSource.setUsername(jdbcusername);
dataSource.setPassword(jdbcPassword);
return dataSource;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
logger.info("transactionManager");
HibernateTransactionManager htm = new HibernateTransactionManager();
htm.setSessionFactory(sessionFactory);
return htm;
}
#Bean
public Properties hibernateProperties() {
logger.info("hibernateProperties");
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.show_sql", "true");
hibernateProperties.setProperty("hibernate.dialect", jdbcDialect);
hibernateProperties.setProperty("hibernate.default_schema", "sms");
return hibernateProperties;
}
}
CustomAuthenticationSuccessHandler Code is attached below
package com.lw.sms;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
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.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Component;
import com.lw.sms.constants.Constants;
import com.lw.sms.user.entities.EmployeeEntity;
import com.lw.sms.user.entities.EmployeePermissionsEntity;
import com.lw.sms.user.service.UserManagementService;
import com.lw.sms.util.QueryBuilder;
#Component("customAuthenticationSuccessHandler")
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private static final Logger logger = LoggerFactory.getLogger(CustomAuthenticationSuccessHandler.class);
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
#Autowired
#Qualifier("sessionInfo")
private SessionInfo sessionInfo;
#Autowired
#Qualifier("userManagementServiceImpl")
private UserManagementService userManagementService;
#Autowired
private HttpServletRequest httpServletRequest;
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException {
response.setStatus(HttpServletResponse.SC_OK);
clearAuthenticationAttributes(request);
handle(request, response);
}
protected void handle(HttpServletRequest request, HttpServletResponse response)
throws IOException {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
EmployeeEntity employeeEntity = (EmployeeEntity) principal;
setSessionInformationForEmployee(employeeEntity);
}
if (response.isCommitted()) {
return;
}
startServices();
redirectStrategy.sendRedirect(request, response, "/dashboard");
}
/**
* #param employeeEntity
*
*/
private void setSessionInformationForEmployee(EmployeeEntity employeeEntity) {
try {
WebAuthenticationDetails details = (WebAuthenticationDetails) SecurityContextHolder.getContext()
.getAuthentication().getDetails();
userManagementService.updateLoginInfo(employeeEntity.getUsername(), details.getRemoteAddress());
// setting session information
} catch (Exception e) {
logger.info("Exception while set Session Information For Employee :" + ExceptionUtils.getFullStackTrace(e));
}
}
private void startServices() {
logger.info("Starting Services..");
try {
String domainName = httpServletRequest.getScheme() + "://" + httpServletRequest.getServerName();
if (httpServletRequest.getServerPort() != 0) {
domainName += ":" + httpServletRequest.getServerPort();
}
domainName += httpServletRequest.getContextPath();
Constants.domainName = domainName + "/resources";
} catch (Exception e) {
logger.error("Error in start services :"+ ExceptionUtils.getFullStackTrace(e));
}
}
protected void clearAuthenticationAttributes(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null) {
return;
}
session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
}
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
this.redirectStrategy = redirectStrategy;
}
protected RedirectStrategy getRedirectStrategy() {
return redirectStrategy;
}
}
UserServiceImpl Code is attached below
package com.lw.sms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.lw.sms.user.dao.UserManagementDAO;
import com.lw.sms.user.entities.EmployeeEntity;
#Service("userServiceImpl")
public class UserServiceImpl implements UserDetailsService {
#Autowired
#Qualifier("userManagementDAOImpl")
private UserManagementDAO userManagementDAO;
#Override
#Transactional
public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
EmployeeEntity employeeEntity = userManagementDAO.loadUserByUsername(username);
if (employeeEntity == null) {
ContractorEntity contractorEntity = userManagementDAO.loadUserByUsernameContractor(username);
if(contractorEntity == null)
throw new AuthenticationCredentialsNotFoundException("Invalid Username or Password");
}
if(!employeeEntity.isEnabled())
throw new AuthenticationCredentialsNotFoundException("Employee Disabled");
return employeeEntity;
}
}
Global Exception Handler Code:
package com.lw.sms;
import java.io.IOException;
import java.nio.charset.Charset;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.stereotype.Controller;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.HttpSessionRequiredException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.support.MissingServletRequestPartException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;
#SuppressWarnings("deprecation")
#Controller
#ControllerAdvice
public class CustomExceptionHandler extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 3699167829164697594L;
private static final Logger logger = LoggerFactory
.getLogger(CustomExceptionHandler.class);
#ExceptionHandler(AuthenticationCredentialsNotFoundException.class)
#ResponseStatus(HttpStatus.UNAUTHORIZED)
public ModelAndView handleLoginExceptions(HttpServletRequest request,
HttpServletResponse response,Exception exception) {
logger.info("Handling exception time error"+ exception.getMessage());
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("login");
return modelAndView;
}
#ExceptionHandler(HttpSessionRequiredException.class)
public String handleSessionExpired() {
logger.info("session-expired");
return "logout";
}
#SuppressWarnings("unchecked")
#ExceptionHandler(value = { MissingServletRequestParameterException.class,
ServletRequestBindingException.class, TypeMismatchException.class,
HttpMessageNotReadableException.class,
MethodArgumentNotValidException.class,
MissingServletRequestPartException.class })
#ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "Bad Request")
#ResponseBody
public JSONObject handle400Exception(Exception ex,HttpServletResponse response) {
logger.error("400 Exception" + ex.getMessage());
JSONObject jsonObject=new JSONObject();
jsonObject.put("status", HttpStatus.BAD_REQUEST);
jsonObject.put("success", false);
jsonObject.put("message", ex.getMessage());
try {
response.getOutputStream().write(jsonObject.toString().getBytes(Charset.defaultCharset()));
} catch (IOException e) {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
response.setContentType("application/json; charset=UTF-8");
return jsonObject;
}
#ExceptionHandler(value = { NoSuchRequestHandlingMethodException.class, })
#ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Not Found")
#ResponseBody
public Boolean handle404Exception(Exception ex) {
logger.error("404 Exception" + ExceptionUtils.getFullStackTrace(ex));
return false;
}
#ExceptionHandler(value = { HttpRequestMethodNotSupportedException.class,
HttpMediaTypeNotSupportedException.class })
#ResponseStatus(value = HttpStatus.NOT_ACCEPTABLE, reason = "Not Supported")
#ResponseBody
public Boolean handle405Exception(Exception ex) {
logger.error("405 Exception" + ExceptionUtils.getFullStackTrace(ex));
return false;
}
#ExceptionHandler(value = { HttpMessageNotWritableException.class,
ConversionNotSupportedException.class })
#ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR, reason = "Internal Server Error")
#ResponseBody
public Boolean handle500Exception(Exception ex) {
logger.error("500 Exception" + ExceptionUtils.getFullStackTrace(ex));
return false;
}
#ExceptionHandler({ Exception.class })
public ModelAndView handleException(Exception ex, HttpServletRequest request,
HttpServletResponse response) {
logger.info("*****************************************************");
logger.error("Exception: " + ExceptionUtils.getFullStackTrace(ex));
ex.printStackTrace();
logger.info("*****************************************************");
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("logout");
return modelAndView;
}
}
This is my HomeController.
package com.lw.sms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import com.lw.sms.master.service.MasterDataService;
import com.lw.sms.user.entities.EmployeeEntity;
/**
* Handles requests for the application home page.
*/
#Controller("homeController")
public class HomeController {
#Autowired
#Qualifier("masterDataServiceImpl")
private MasterDataService masterDataService;
#Autowired
#Qualifier("sessionInfo")
private SessionInfo sessionInfo;
#GetMapping(value = { "/home", "/", "login" })
public ModelAndView home() {
return new ModelAndView("login");
}
#GetMapping(value = "dashboard")
public ModelAndView dashboard() {
EmployeeEntity user = sessionInfo.getEmployeeEntity();
return new ModelAndView("dashboard", "userDetails", user);
}
// Logout page
#ResponseStatus(code = HttpStatus.UNAUTHORIZED)
#GetMapping(value = "logout")
public String logout() {
return "logout";
}
}
Could you please try adding the successForwardUrl also as below.
http.authorizeRequests().antMatchers("/login").permitAll()
.antMatchers("/dashboard").access("IS_AUTHENTICATED_FULLY")
.antMatchers("/j_spring_security_check").access("IS_AUTHENTICATED_ANONYMOUSLY")
.and().formLogin().loginPage("/login").usernameParameter("employeeId").passwordParameter("password")
.successForwardUrl("/dashboard").defaultSuccessUrl("/dashboard", true).failureForwardUrl("/loginfailed")
.loginProcessingUrl("/j_spring_security_check")
.and().logout().logoutSuccessUrl("/logout").invalidateHttpSession(true)
.and().sessionManagement().sessionFixation().none()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.invalidSessionUrl("/login")
.and().exceptionHandling().accessDeniedPage("/Access_Denied").and().csrf().disable();
I was able to replicate the error.
I had to configure a new bean in SecurityConfig file.
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userServiceImpl);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
This question already has answers here:
Why is my Spring #Autowired field null?
(21 answers)
Closed 3 years ago.
In my application I have autowired dataSource object which is being returned null.
The object is being used in DAO class.
Application Flow ->
1.OAConsumer.java starts execution
2. calls service.java
3. calls insertOffset in KafkaDAOImpl class
IDE used in eclispe Oxygen.
Code and error details below.
Error shown
java.lang.NullPointerException
at com.oa.dao.KafkaOffsetDAOImpl.insertOffset(KafkaOffsetDAOImpl.java:36)
at com.oa.services.Service.savePayload(Service.java:54)
at com.oa.consumer.OAConsumer.orderConsumer(OAConsumer.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:170)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:120)
at org.springframework.kafka.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:48)
at org.springframework.kafka.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:283)
at org.springframework.kafka.listener.adapter.BatchMessagingMessageListenerAdapter.invoke(BatchMessagingMessageListenerAdapter.java:146)
at org.springframework.kafka.listener.adapter.BatchMessagingMessageListenerAdapter.onMessage(BatchMessagingMessageListenerAdapter.java:138)
at org.springframework.kafka.listener.adapter.BatchMessagingMessageListenerAdapter.onMessage(BatchMessagingMessageListenerAdapter.java:59)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeBatchOnMessage(KafkaMessageListenerContainer.java:1052)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeBatchOnMessage(KafkaMessageListenerContainer.java:1036)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeBatchListener(KafkaMessageListenerContainer.java:998)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeBatchListener(KafkaMessageListenerContainer.java:938)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeListener(KafkaMessageListenerContainer.java:921)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.pollAndInvoke(KafkaMessageListenerContainer.java:740)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.run(KafkaMessageListenerContainer.java:689)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
KafkaOffsetDAOImpl.java
package com.oa.dao;
import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import com.oa.model.KafkaOffsetRecord;
public class KafkaOffsetDAOImpl implements KafkaOffsetDAO {
// #Autowired
// JdbcTemplate jdbcTemplate;
#Autowired
DataSource dataSource;
#Override
public boolean insertOffset(KafkaOffsetRecord offsetRecord) {
boolean status=false;
try(Connection connection =dataSource.getConnection()){
if(connection.isValid(10000))
status= true;
}catch (Exception e) {
e.printStackTrace();
}
return false;
}
OracleConfig.java
package com.oa.config;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
#Configuration
public class OracleConfig {
private static final Logger logger = LoggerFactory.getLogger(OracleConfig.class);
#Value("${spring.datasource.url}")
private String url;
#Value("${spring.datasource.username}")
private String username;
#Value("${spring.datasource.password}")
private String password;
#Value("${spring.datasource.driver-class-name}")
private String driverClassName;
#Value("${spring.datasource.maximumPoolSize}")
private int maxPoolSize;
#Value("${spring.datasource.minimumIdle}")
private int minIdle;
#Value("${spring.datasource.connectionTimeout}")
private long connTimeOut;
#Value("${spring.datasource.idleTimeout}")
private long idleTimeout;
//
/**
* See http://www.baeldung.com/hikaricp
*/
#Bean
public HikariDataSource dataSource() {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName(driverClassName);
hikariConfig.setUsername(username);
hikariConfig.setPassword(password);
hikariConfig.setJdbcUrl(url);
hikariConfig.setMaximumPoolSize(maxPoolSize);
hikariConfig.setConnectionTimeout(connTimeOut);
hikariConfig.setMinimumIdle(minIdle);
hikariConfig.setIdleTimeout(idleTimeout);
HikariDataSource hikariDataSource = new HikariDataSource(hikariConfig);
if (hikariDataSource.isRunning()) {
logger.info("------> Oracle DB connection created successfully.");
}
return hikariDataSource;
}
Consumer.java
package com.oa.consumer;
import java.util.List;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.kafka.support.KafkaHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Payload;
import com.oa.services.OrderService;
public class OAConsumer {
private static final Logger LOGGER = LoggerFactory.getLogger(OAConsumer.class);
#KafkaListener(topics = "**removed**", groupId = "**removed**")
public void orderConsumer(List<ConsumerRecord<String, String>> records, Acknowledgment acknowledgment) {
LOGGER.debug("START :: orderConsumer");
OrderService orderService = new OrderService();
try {
for (ConsumerRecord<String, String> record : records) {
LOGGER.debug("Processing Offset Order :: offset={} :: partitionId={} :: topicName={}", record.offset(),
record.partition(), record.topic());
orderService.savePayload(record);
}
acknowledgment.acknowledge();
LOGGER.debug("END :: orderConsumer:: Acknowledged");
} catch (Exception exception) {
exception.printStackTrace();
LOGGER.error(exception.getMessage());
}
}
Service.java
package com.oa.services;
import java.io.IOException;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.oa.dao.KafkaOffsetDAO;
import com.oa.dao.KafkaOffsetDAOImpl;
import com.oa.model.KafkaOffsetRecord;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Service {
private static final Logger LOGGER = LoggerFactory.getLogger(Service.class);
public Boolean checkOAEligible(String message, long offset, String topic) throws IOException {
return true;
}
public Boolean savePayload(ConsumerRecord<String, String> record) {
LOGGER.debug("START:: saveOrderPayload ::offset= {} :: topic= {}", record.offset(), record.topic());
Boolean status = false;
KafkaOffsetDAO dao = new KafkaOffsetDAOImpl();
try {
if (checkOAEligible(record.value(), record.offset(), record.topic())) {
KafkaOffsetRecord kafkaOffsetRecord= new KafkaOffsetRecord(record);
status = dao.insertOffset(kafkaOffsetRecord);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
LOGGER.debug("END:: saveOrderPayload :: offset={} :: topic={} , status={}", record.offset(), record.topic(), status);
return status;
}
}
KafkaOffsetRecord
package com.oa.model;
import org.apache.kafka.clients.consumer.ConsumerRecord;
public class KafkaOffsetRecord {
long offsetId;
String jsonMsg;
String kafkaSourceType;
int partitionId;
String kafkaTopicName;
public KafkaOffsetRecord() {
}
public KafkaOffsetRecord(ConsumerRecord<String, String> consumerRecord) {
offsetId = consumerRecord.offset();
jsonMsg = consumerRecord.value();
partitionId=consumerRecord.partition();
kafkaTopicName= consumerRecord.topic();
kafkaSourceType = "TEST";
}
public long getOffsetId() {
return offsetId;
}
public String getJsonMsg() {
return jsonMsg;
}
public String getKafkaSourceType() {
return kafkaSourceType;
}
public int getPartitionId() {
return partitionId;
}
public String getKafkaTopicName() {
return kafkaTopicName;
}
public void setOffsetId(long offsetId) {
this.offsetId = offsetId;
}
public void setJsonMsg(String jsonMsg) {
this.jsonMsg = jsonMsg;
}
public void setKafkaSourceType(String kafkaSourceType) {
this.kafkaSourceType = kafkaSourceType;
}
public void setPartitionId(int partitionId) {
this.partitionId = partitionId;
}
public void setKafkaTopicName(String kafkaTopicName) {
this.kafkaTopicName = kafkaTopicName;
}
}
application.properties
spring.datasource.url=jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS_LIST=(LOAD_BALANCE=ON)(FAILOVER=OFF)(ADDRESS=(PROTOCOL=TCP)(HOST=**removed**)(PORT=**removed**))(ADDRESS=(PROTOCOL=TCP)(HOST=**removed**)(PORT=**removed**)))(CONNECT_DATA=(SERVICE_NAME=**removed**)(SERVER=DEDICATED)))
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.username=**removed**
spring.datasource.password=**removed**
spring.datasource.type=oracle.jdbc.pool.OracleDataSource
spring.datasource.maximumPoolSize=20
spring.datasource.minimumIdle=5
spring.datasource.connectionTimeout=30000
spring.datasource.idleTimeout=1500000
use constructor injection, when you use it
public class KafkaOffsetDAOImpl implements KafkaOffsetDAO {
private final DataSource dataSource;
#Autowired
KafkaOffsetDAOImpl(final Datasource datasrouce) {
this.dataSource = dataSource;
}
this way you can be sure, that spring creates the autowired field and injects it.
I tried to much things and it doesn't worked. I want the data inserted on my DB to rollback when an error occurs on vacationsDao.requestVacations. Here's my code:
VacationsService:
import java.text.ParseException;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.autozone.web.dao.VacationsDao;
import com.autozone.web.exception.InvalidVacationsException;
#Service
public class VacationsServiceImpl implements VacationsService {
private ValidationService validationService;
private VacationsDao vacationsDao;
#Autowired
public VacationsServiceImpl(ValidationService validationService,
VacationsDao vacationsDao) {
this.validationService = validationService;
this.vacationsDao = vacationsDao;
}
#Override
#Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public void requestVacations(String username, Set<String> days)
throws InvalidVacationsException {
if (validationService.validateUsername(username)) {
for (String day : days) {
try {
if (!validationService.validateDate(day)) {
throw new InvalidVacationsException(
"Wrong date format. Must use 'yyyy-MM-dd'.");
}
} catch (ParseException e) {
e.printStackTrace();
throw new InvalidVacationsException(
"Wrong date format. Must use 'yyyy-MM-dd'.");
}
}
try {
vacationsDao.requestVacations(username, days);
} catch (DuplicateKeyException e) {
throw new InvalidVacationsException(
"Dates already requested from this user.");
}
} else {
throw new InvalidVacationsException(
"Wrong username format. Must only contains alphanumeric and starts with letters.");
}
}
}
VacationsDao
import java.util.Set;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
#Repository
public class VacationsDaoImpl implements VacationsDao {
JdbcTemplate jdbcTemplate;
#Autowired
public void setDataSource(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
// It inserts all data when an exception occurs. Check later.
#Override
public void requestVacations(String username, Set<String> days)
throws DuplicateKeyException {
StringBuilder insert = new StringBuilder(
"INSERT INTO cc_vacations(username, day) VALUES ");
String prefix = "";
for (String day : days) {
insert.append(prefix);
insert.append("('");
insert.append(username);
insert.append("', '");
insert.append(day);
insert.append("')");
prefix = ",";
}
jdbcTemplate.update(insert.toString());
}
}
DbConfig
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
public class DbConfig {
#Bean
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://callcenter.autozone.com/callcenter");
dataSource.setUsername("callcenter");
dataSource.setPassword("h3lp1n5");
return dataSource;
}
#Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(getDataSource());
}
}
Thanks for your help! :)