Repository
package com.example.demo.jpa;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.example.demo.entity.Person;
#Repository
#Transactional
public class RepositoryJpa {
#PersistenceContext
EntityManager entityManager;
//#Autowired
Person person = new Person();
public Person findById(int id) {
System.out.println("value of parameter id is "+id);
return entityManager.find(Person.class,id);
}
public Person update(Person person) {
return entityManager.merge(person);
}
}
Entity table:
package com.example.demo.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
//#Table(name="person")
public class Person {
#Id
private int id;
private String name;
private String location;
private String birth_date;
// public Person(int i, String string, String string2, String string3) {}
public Person(int id, String name, String location, String birth_date) {
// super();
this.id = id;
this.name = name;
this.location = location;
this.birth_date = birth_date;
}
public Person(String name, String location, String birth_date) {
// super();
this.name = name;
this.location = location;
this.birth_date = birth_date;
}
public Person() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
System.out.println("i called setID=" + this.id);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
System.out.println("i called setName=" + this.name);
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
System.out.println("i called setLocation=" + this.location);
}
public String getBirth_date() {
return birth_date;
}
public void setBirth_date(String birth_date) {
this.birth_date = birth_date;
// System.out.println("i called setBirth_ID="+this.birth_date);
}
/*
* #Override public String toString() { return "Person [id=" + id + ", name=" +
* name + ", location=" + location + ", birth_date=" + birth_date + ", getId()="
* + getId() + ", getName()=" + getName() + ", getLocation()=" + getLocation() +
* ", getBirth_date()=" + getBirth_date() + "]"; }
*/
}
SpringBootApplication
package com.example.demo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import com.example.demo.entity.Person;
import com.example.demo.jpa.RepositoryJpa;
#SpringBootApplication
public class JpaDemoApplication implements CommandLineRunner {
private Logger logger=LoggerFactory.getLogger(this.getClass());
//#Autowired
Person person = new Person();
RepositoryJpa repo = new RepositoryJpa();
public static void main(String[] args) {
// TODO Auto-generated method stub
SpringApplication.run(JpaDemoApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
System.out.println("hello all");
logger.info("find by id -> {}", repo.findById(2));
logger.info("insert user-> {}",repo.update(new Person(5,"gaurav","chicago","05/06/82")));
}
}
Application Properties
spring.h2.console.enabled=true
#spring.datasource.url=jdbc:h2:mem:testdb
#spring.batch.job.enabled=false
spring.jpa.show-sql=true
##EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
spring.jpa.defer-datasource-initialization=true
I'm a beginner to SpringBoot and I don't know what wrong I'm doing related to entity manager method it giving the error of and also #Autowired not working, I'm manually creating the object!
Help me please!!!
Console error screenshot also shared below please check:
Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:780) ~[spring-boot-2.6.4.jar:2.6.4]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:761) ~[spring-boot-2.6.4.jar:2.6.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[spring-boot-2.6.4.jar:2.6.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[spring-boot-2.6.4.jar:2.6.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.4.jar:2.6.4]
at com.example.demo.JpaDemoApplication.main(JpaDemoApplication.java:31) ~[classes/:na]
Caused by: java.lang.NullPointerException: null
at com.example.demo.jpa.RepositoryJpa.update(RepositoryJpa.java:31) ~[classes/:na]
at com.example.demo.JpaDemoApplication.run(JpaDemoApplication.java:46) ~[classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:777) ~[spring-boot-2.6.4.jar:2.6.4]
... 5 common frames omitted
console
You should Autowire the repository bean in JpaDemoApplication class, you should never create an object for spring component using new keyword
#SpringBootApplication
public class JpaDemoApplication implements CommandLineRunner {
private Logger logger=LoggerFactory.getLogger(this.getClass());
#Autowired
RepositoryJpa repositoryJpa;
public static void main(String[] args) {
// TODO Auto-generated method stub
SpringApplication.run(JpaDemoApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
System.out.println("hello all");
logger.info("find by id -> {}", repo.findById(2));
logger.info("insert user-> {}",repo.update(new Person(5,"gaurav","chicago","05/06/82")));
}
}
Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'endpointHandlerMapping' defined in class path resource [com/myorg/api/web/AppConfig.class]: Invocation of init method failed; nested exception is java.lang.StackOverflowError
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1799) ~[spring-beans-5.2.17.RELEASE.jar:5.2.17.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.17.RELEASE.jar:5.2.17.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.17.RELEASE.jar:5.2.17.RELEASE]
at
<----------The AppConfig.java----------------->
package com.myorg.api.web;
import com.myorg.api.web.properties.ThreadPoolProperties;
import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ThreadPoolExecutor;
#Configuration
public class AppConfig
{
private static final String BUNDLE_API_THREAD_NAME_PREFIX = "BUNDLE-API-THREAD-";
private static final String HISTORICAL_API_THREAD_NAME_PREFIX = "HISTORICAL-API-THREAD-";
#Bean
#ConfigurationProperties(prefix = "historical-api-thread-pool")
public ThreadPoolProperties historicalApiThreadPool()
{
return new ThreadPoolProperties();
}
#Bean
#ConfigurationProperties(prefix = "bundle-api-thread-pool")
public ThreadPoolProperties bundleApiThreadPool()
{
return new ThreadPoolProperties();
}
#Bean
public ThreadPoolTaskExecutor bundleAPIThreadPoolTaskExecutor(final ThreadPoolProperties bundleApiThreadPool)
{
return createThreadPoolTaskExecutor(bundleApiThreadPool.getCorePoolSize(), bundleApiThreadPool.getMaxPoolSize(),
bundleApiThreadPool.getQueueCapacity(), bundleApiThreadPool.isAllowCoreThreadTimeOut(),
bundleApiThreadPool.getKeepAliveSeconds(), BUNDLE_API_THREAD_NAME_PREFIX);
}
#Bean
public ThreadPoolTaskExecutor historicalAPIThreadPoolTaskExecutor(final ThreadPoolProperties historicalApiThreadPool)
{
return createThreadPoolTaskExecutor(historicalApiThreadPool.getCorePoolSize(),
historicalApiThreadPool.getMaxPoolSize(),
historicalApiThreadPool.getQueueCapacity(), historicalApiThreadPool.isAllowCoreThreadTimeOut(),
historicalApiThreadPool.getKeepAliveSeconds(), HISTORICAL_API_THREAD_NAME_PREFIX);
}
private ThreadPoolTaskExecutor createThreadPoolTaskExecutor(Integer threadPoolCorePoolSize,
Integer threadPoolMaxPoolSize, int threadPoolQueueCapacity,
boolean threadPoolAllowCoreThreadTimeOut, int threadPoolKeepAliveSeconds,
String threadNamePrefix)
{
final ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
if (threadPoolCorePoolSize != null)
{
pool.setCorePoolSize(threadPoolCorePoolSize);
}
else
{
pool.setCorePoolSize(Runtime.getRuntime().availableProcessors());
}
if (threadPoolMaxPoolSize != null)
{
pool.setMaxPoolSize(threadPoolMaxPoolSize);
}
else
{
pool.setMaxPoolSize(Runtime.getRuntime().availableProcessors() * 2);
}
pool.setQueueCapacity(threadPoolQueueCapacity);
pool.setAllowCoreThreadTimeOut(threadPoolAllowCoreThreadTimeOut);
pool.setKeepAliveSeconds(threadPoolKeepAliveSeconds);
pool.setThreadNamePrefix(threadNamePrefix);
pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
pool.initialize();
return pool;
}
#Bean(name = "mvcHandlerMappingIntrospector")
public HandlerMappingIntrospector mvcHandlerMappingIntrospector() {
return new HandlerMappingIntrospector();
}
}
How to classify the elements using Spring Batch ? I want to write data into two different tables or files for now doing this in the console.
Error:
The method stream(ItemStream) in the type AbstractTaskletStepBuilder> is not applicable for the arguments (ItemWriter)
#EnableBatchProcessing
#SpringBootApplication
public class ClassifierCompositeItemApplication {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
#Value("classpath:input/customer.csv")
private Resource inputResource;
public ClassifierCompositeItemApplication(JobBuilderFactory jobs, StepBuilderFactory steps) {
this.jobBuilderFactory = jobs;
this.stepBuilderFactory = steps;
}
#Bean
#StepScope
public FlatFileItemReader<Customer> classifierCompositeWriterItemReader() {
return new FlatFileItemReaderBuilder<Customer>()
.name("customerFileReader")
.resource(inputResource)
.delimited()
.names(new String[] { "firstName", "middleInitial", "lastName", "address", "city", "state", "zip" })
.targetType(Customer.class)
.build();
}
#Bean
public ClassifierCompositeItemWriter<Customer> compositeItemWriter() throws IOException {
final Classifier<Customer, ItemStreamWriter<? super Customer>> classifier = new CustomerClassifier(
this.customer1(), this.customer2());
return new ClassifierCompositeItemWriterBuilder<Customer>()
.classifier(classifier)
.build();
}
#Bean
#StepScope
public ItemStreamWriter<Customer> customer1() throws IOException {
System.out.println("Customer #1");
return new ItemStreamWriter<Customer>() {
#Override
public void open(ExecutionContext executionContext) throws ItemStreamException {
}
#Override
public void update(ExecutionContext executionContext) throws ItemStreamException {
}
#Override
public void close() throws ItemStreamException {
}
#Override
public void write(List<? extends Customer> items) throws Exception {
for (Customer customer : items) {
System.out.println(customer);
}
}
};
}
#Bean
public ItemStreamWriter<NewCustomer> customer2() {
System.out.println("Customer #2");
return new ItemStreamWriter<NewCustomer>() {
#Override
public void open(ExecutionContext executionContext) throws ItemStreamException {
}
#Override
public void update(ExecutionContext executionContext) throws ItemStreamException {
}
#Override
public void close() throws ItemStreamException {
}
#Override
public void write(List<? extends NewCustomer> items) throws Exception {
for (NewCustomer customer : items) {
System.out.println(customer);
}
}
};
}
#Bean
public Step classifierCompositeWriterStep() throws IOException {
return this.stepBuilderFactory.get("compositeWriterStep")
.<Customer, Customer>chunk(10)
.reader(this.classifierCompositeWriterItemReader())
.writer(this.compositeItemWriter())
.stream(this.customer1())
.stream(this.customer2())
.build();
}
#Bean
public Job classifierCompositeWriterJob() throws IOException {
return this.jobBuilderFactory.get("compositeWriterJob")
.start(this.classifierCompositeWriterStep())
.build();
}
public static void main(String[] args) {
SpringApplication.run(ClassifierCompositeItemApplication.class, args);
}
}
CustomerClassifier.java
#Data
public class CustomerClassifier implements Classifier<Customer, ItemStreamWriter<? super Customer>> {
private static final long serialVersionUID = 1L;
private final ItemStreamWriter<Customer> fileItemWriter;
private final ItemStreamWriter<Customer> jdbcItemWriter;
#Override
public ItemStreamWriter<? super Customer> classify(Customer customer) {
if (customer.getState().matches("^[A-M].*")) {
return fileItemWriter;
} else {
return jdbcItemWriter;
}
}
}
Customer.java
#Data
public class Customer implements Serializable {
private String firstName;
private String middleInitial;
private String lastName;
private String address;
private String city;
private String state;
private String zip;
#Override
public String toString() {
return "Customer{" + ", firstName='" + firstName + '\'' + ", middleInitial='" + middleInitial + '\''
+ ", lastName='" + lastName + '\'' + ", address='" + address + '\'' + ", city='" + city + '\''
+ ", state='" + state + '\'' + ", zip='" + zip + '\'' + '}';
}
}
Schema.sql
CREATE TABLE springbatch.TBL_CUSTOMER_WRITER (
firstname varchar NULL,
middleinitial varchar NULL,
lastname varchar NULL,
address varchar NULL,
city varchar NULL,
state varchar NULL,
zipcode varchar NULL
)
WITH (
OIDS=FALSE
) ;
Customer.csv
Richard,N,Darrow,5570 Isabella Ave,St. Louis,IL,58540
Barack,G,Donnelly,7844 S. Greenwood Ave,Houston,CA,38635
Ann,Z,Benes,2447 S. Greenwood Ave,Las Vegas,NY,55366
Laura,9S,Minella,8177 4th Street,Dallas,FL,04119
Erica,Z,Gates,3141 Farnam Street,Omaha,CA,57640
Warren,L,Darrow,4686 Mt. Lee Drive,St. Louis,NY,94935
Warren,M,Williams,6670 S. Greenwood Ave,Hollywood,FL,37288
Harry,T,Smith,3273 Isabella Ave,Houston,FL,97261
Steve,O,James,8407 Infinite Loop Drive,Las Vegas,WA,90520
Erica,Z,Neuberger,513 S. Greenwood Ave,Miami,IL,12778
Aimee,C,Hoover,7341 Vel Avenue,Mobile,AL,35928
Jonas,U,Gilbert,8852 In St.,Saint Paul,MN,57321
Regan,M,Darrow,4851 Nec Av.,Gulfport,MS,33193
Stuart,K,Mckenzie,5529 Orci Av.,Nampa,ID,18562
Sydnee,N,Robinson,894 Ornare. Ave,Olathe,KS,25606
You are registering your delegate item writers as streams here:
.stream(this.customer1())
.stream(this.customer2())
But those are not ItemStreams. You need to change the return type of the methods customer1() and customer2() to ItemStreamWriter.
EDIT: Add an example:
import java.util.Arrays;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
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.JobLauncher;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ClassifierCompositeItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.batch.item.support.builder.ClassifierCompositeItemWriterBuilder;
import org.springframework.classify.Classifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
#EnableBatchProcessing
public class MyJob {
#Bean
public ItemReader<Customer> itemReader() {
return new ListItemReader<>(Arrays.asList(new Customer("foo"), new Customer("bar")));
}
#Bean
public ItemWriter<Customer> fooWriter() {
return items -> {
for (Customer item : items) {
System.out.println("foo writer: item " + item.name);
}
};
}
#Bean
public ItemWriter<Customer> barWriter() {
return items -> {
for (Customer item : items) {
System.out.println("bar writer: item " + item.name);
}
};
}
#Bean
public ClassifierCompositeItemWriter<Customer> classifierCompositeItemWriter() {
final Classifier<Customer, ItemWriter<? super Customer>> classifier =
new CustomerClassifier(this.fooWriter(), this.barWriter());
return new ClassifierCompositeItemWriterBuilder<Customer>()
.classifier(classifier)
.build();
}
#Bean
public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) {
return jobs.get("job")
.start(steps.get("step")
.<Customer, Customer>chunk(5)
.reader(itemReader())
.writer(classifierCompositeItemWriter())
.build())
.build();
}
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(MyJob.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
jobLauncher.run(job, new JobParameters());
}
static class Customer {
String name;
public Customer(String name) {
this.name = name;
}
}
static class CustomerClassifier implements Classifier<Customer, ItemWriter<? super Customer>> {
private ItemWriter<? super Customer> fooItemWriter;
private ItemWriter<? super Customer> barItemWriter;
public CustomerClassifier(ItemWriter<? super Customer> fooItemWriter, ItemWriter<? super Customer> barItemWriter) {
this.fooItemWriter = fooItemWriter;
this.barItemWriter = barItemWriter;
}
#Override
public ItemWriter<? super Customer> classify(Customer customer) {
return customer.name.startsWith("f") ? fooItemWriter : barItemWriter;
}
}
}
This prints:
foo writer: item foo
bar writer: item bar
It seems BeanPostProcessor interface implementation is having impact on #ServiceActivator. What should be the way to use BeanPostProcessor with #ServiceActivator. Thanks.
Complete logs are available here logs
Following is Java Config used for SFTP -
package com.ftp.example;
import java.io.File;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.file.FileNameGenerator;
import org.springframework.integration.file.remote.session.CachingSessionFactory;
import org.springframework.integration.file.remote.session.SessionFactory;
import org.springframework.integration.sftp.outbound.SftpMessageHandler;
import org.springframework.integration.sftp.session.DefaultSftpSessionFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import com.jcraft.jsch.ChannelSftp.LsEntry;
#Configuration
#EnableScheduling
#EnableAspectJAutoProxy
#EnableAsync
#IntegrationComponentScan
#EnableIntegration
#EnableBatchProcessing
#PropertySource("file:C:\\DEV\\workspace_oxygen\\ftp-example\\ftp-example.properties")
public class DependencySpringConfiguration {
private Logger LOG = LoggerFactory.getLogger(DependencySpringConfiguration.class);
#Value("${project.name}")
private String applicationName;
#Value("${${project.name}.ftp.server}")
private String server;
#Value("${${project.name}.ftp.port}")
int port;
#Value("${${project.name}.ftp.username}")
private String username;
#Value("${${project.name}.ftp.password}")
private String password;
#Value("${${project.name}.ftp.remote.directory}")
private String remoteDirectory;
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
#Bean
public ProcessStarter processStarter() {
return new ProcessStarter();
}
/* #Bean
public LogInjector logInjector() {
return new LogInjector();
}*/
#Bean
public FTPOutService fTPOutService() {
return new FTPOutService();
}
#Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
DefaultSftpSessionFactory sf = new DefaultSftpSessionFactory();
sf.setHost(server);
sf.setPort(port);
sf.setUser(username);
sf.setPassword(password);
sf.setAllowUnknownKeys(true);
return new CachingSessionFactory<LsEntry>(sf);
}
#Bean
#ServiceActivator(inputChannel = "toSftpChannel")
public MessageHandler handler() {
SftpMessageHandler handler = new SftpMessageHandler(sftpSessionFactory());
handler.setRemoteDirectoryExpression(new LiteralExpression(remoteDirectory));
handler.setFileNameGenerator(new FileNameGenerator() {
#Override
public String generateFileName(Message<?> message) {
return "fileNameToBeFtp.txt";
}
});
return handler;
}
#MessagingGateway
public interface MyGateway {
#Gateway(requestChannel = "toSftpChannel")
void sendToSftp(File file);
}
}
And We are calling gateway object like this while doing SFTP
Main class
public class FtpExample {
public static String[] ARGS;
private static final Logger LOG = LoggerFactory.getLogger(FtpExample.class);
public static void main(String[] args) throws Exception {
ARGS = args;
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(DependencySpringConfiguration.class);
ProcessStarter processStarter = ctx.getBean(ProcessStarter.class);
processStarter.startService();
}
}
Other classes -
public class ProcessStarter {
#Inject
private FTPOutService ftpOutService;
public void startService() {
ftpOutService.ftpToBbg();
}
}
public class FTPOutService {
private static Logger log = LoggerFactory.getLogger(FTPOutService.class);
#Inject
private ApplicationContext appContext;
public void ftpToBbg() {
log.info("Starting FTP out process...");
File file = null;
try {
file = new File("C:\\Temp\\log\\debug\\ftp\\priceindex\\for-upload\\ftp-example.txt.REQ");
MyGateway gateway = appContext.getBean(MyGateway.class);
gateway.sendToSftp(file);
log.info("File {} written successfully on remote server", file);
} catch (Exception e) {
log.error("Error while uploading file {}", file, e);
}
}
}
Above code is working fine unless I am not adding following bean declaration in above defined Java Config -
public LogInjector logInjector() {
return new LogInjector();
}
Above bean definition is having following implementation -
public class LogInjector implements BeanPostProcessor {
#Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
#Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
#Override
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
// make the field accessible if defined private
ReflectionUtils.makeAccessible(field);
if (field.getAnnotation(Log.class) != null) {
if (org.slf4j.Logger.class == field.getType()) {
org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(bean.getClass());
field.set(bean, log);
} else if (java.util.logging.Logger.class == field.getType()) {
java.util.logging.Logger log = java.util.logging.Logger.getLogger(bean.getClass().toString());
field.set(bean, log);
}
}
}
});
return bean;
}
}
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.FIELD)
#Documented
public #interface Log {
}
Once any BeanPostProcessor implementation is added in Java Config, it creates problem and application not able to see toSftpChannel -
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
bean named 'toSftpChannel' available at
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:685)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1199)
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at
org.springframework.integration.support.channel.BeanFactoryChannelResolver.resolveDestination(BeanFactoryChannelResolver.java:88)
at
org.springframework.integration.support.channel.BeanFactoryChannelResolver.resolveDestination(BeanFactoryChannelResolver.java:45)
at
org.springframework.integration.gateway.MessagingGatewaySupport.getRequestChannel(MessagingGatewaySupport.java:327)
at
org.springframework.integration.gateway.MessagingGatewaySupport.send(MessagingGatewaySupport.java:368)
at
org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:477)
at
org.springframework.integration.gateway.GatewayProxyFactoryBean.doInvoke(GatewayProxyFactoryBean.java:429)
at
org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.java:420)
at
org.springframework.integration.gateway.GatewayCompletableFutureProxyFactoryBean.invoke(GatewayCompletableFutureProxyFactoryBean.java:65)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy57.sendToSftp(Unknown Source)
Looks what you have:
#Bean
public LogInjector logInjector() {
return new LogInjector();
}
If you declare BeanPostProcessors as #Bean you have to specify them with the static modifier: https://docs.spring.io/spring/docs/5.0.0.RELEASE/spring-framework-reference/core.html#beans-factorybeans-annotations
You may declare #Bean methods as static, allowing for them to be called without creating their containing configuration class as an instance. This makes particular sense when defining post-processor beans, e.g. of type BeanFactoryPostProcessor or BeanPostProcessor, since such beans will get initialized early in the container lifecycle and should avoid triggering other parts of the configuration at that point.
The sessionFactory Bean which is autowired in my DAO is always showingup to be null. below is my project.
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.ClassPathResource;
#Configuration
#Import({HibernateConfig.class})
public class AppConfig {
#Bean
public PropertyPlaceholderConfigurer propertyPlaceHolderConfigurer(){
PropertyPlaceholderConfigurer prop = new PropertyPlaceholderConfigurer();
prop.setLocation(new ClassPathResource("dbProperties.properties"));
prop.setIgnoreUnresolvablePlaceholders(true);
return prop;
}
}
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBuilder;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.model.Person;
#Configuration
//#EnableTransactionManagement
//#PropertySource(value={"classpath:dbProperties.properties"})
public class HibernateConfig {
#Value("${driverClassName}")
private String driverClassName;
#Value("${url}")
private String url;
#Value("${username}")
private String username;
#Value("${password}")
private String password;
#Value("${hibernate.dialect}")
private String hibernateDielect;
#Value("${hibernate.show_sql}")
private String hibernateShowSQL;
#Value("${hibernate.hbm2ddl.auto}")
private String hibernateHbm2Ddlauto;
#Bean
public DataSource datasource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
public Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", hibernateDielect);
properties.put("hibernate.show_sql", hibernateShowSQL);
properties.put("hibernate.hbm2ddl.auto", hibernateHbm2Ddlauto);
return properties;
}
#Bean
#Autowired
public SessionFactory sessionFactory(DataSource dataSource) {
LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
sessionBuilder.scanPackages("com.configuration");
sessionBuilder.addAnnotatedClass(Person.class);
sessionBuilder.addProperties(hibernateProperties());
return sessionBuilder.buildSessionFactory();
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory);
return transactionManager;
}
}
import java.util.List;
import com.model.Person;
public interface PersonDao {
void savePerson(Person persom);
void deletePerson(String taxid);
List<Person> getAllPersons();
Person updatePerson(Person person);
Person findPersonById(String taxid);
}
import java.util.List;
import javax.transaction.Transactional;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.model.Person;
#Service
public class PersonDaoImpl implements PersonDao {
#Autowired
SessionFactory sessionFactory;
#Override
#Transactional
public void savePerson(Person person) {
sessionFactory.getCurrentSession().persist(person);
}
#Override
#Transactional
public void deletePerson(String taxid) {
// TODO Auto-generated method stub
// Criteria criteria = getSession().createCriteria(Person.class);
Query query = sessionFactory.getCurrentSession().createSQLQuery("DELETE FROM PERSON WHERE taxid = :taxid");
query.setString(taxid, "taxid");
}
#SuppressWarnings("unchecked")
#Override
#Transactional
public List<Person> getAllPersons() {
// TODO Auto-generated method stub
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Person.class);
return (List<Person>) criteria.list();
}
#Override
#Transactional
public Person updatePerson(Person person) {
// TODO Auto-generated method stub
sessionFactory.getCurrentSession().update(person);
return person;
}
#Override
#Transactional
public Person findPersonById(String taxid) {
// TODO Auto-generated method stub
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Person.class);
criteria.add(Restrictions.eq("taxid", taxid));
return (Person) criteria.uniqueResult();
}
}
import java.sql.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name ="person")
public class Person {
#Column(name ="FIRSTNAME")
private String firstName;
#Column(name ="LASTNAME")
private String lastName;
#Column(name ="DOB")
private Date DOB;
#Column(name ="TAXID")
#Id
private String taxid;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Date getDOB() {
return DOB;
}
public void setDOB(Date dOB) {
DOB = dOB;
}
public String getTaxid() {
return taxid;
}
public void setTaxid(String taxid) {
this.taxid = taxid;
}
#Override
public String toString() {
return "Person [firstName=" + firstName + ", lastName=" + lastName + ", DOB=" + DOB + ", taxid=" + taxid + "]";
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((DOB == null) ? 0 : DOB.hashCode());
result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
result = prime * result + ((taxid == null) ? 0 : taxid.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (DOB == null) {
if (other.DOB != null)
return false;
} else if (!DOB.equals(other.DOB))
return false;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
if (taxid == null) {
if (other.taxid != null)
return false;
} else if (!taxid.equals(other.taxid))
return false;
return true;
}
}
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import com.configuration.AppConfig;
import com.dao.PersonDaoImpl;
import com.model.Person;
public class AppMain {
public static void main(String args[]) {
AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Person person = new Person();
person.setFirstName("Akhil");
person.setLastName("goli");
person.setTaxid("123abc456");
PersonDaoImpl impl = new PersonDaoImpl();
impl.savePerson(person);
}
}
Exception in thread "main" java.lang.NullPointerException at
com.dao.PersonDaoImpl.savePerson(PersonDaoImpl.java:25) at
main.AppMain.main(AppMain.java:20)
You have to call afterPropertiesSet() for initializing the bean. Now you only created the bean but not initialized.
I figured it out. As I was using Hibernate4 I need to use
StandardServiceRegistryBuilder class to get SessionFactory.
Hope this snippet helps.
public class HibernateUtil {
public SessionFactory getSessionFactory()
{
Configuration config = new Configuration().configure();
StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder().applySettings(config.getProperties());
SessionFactory session = config.buildSessionFactory(serviceRegistryBuilder.build());
return session;
}
I am putting sessionFactory configuration code here. Hope it will help you.
#Bean
// #Autowired
// #Bean(name = "sessionFactory")
public SessionFactory sessionFactory() throws IOException {
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
hibernateProperties.put("hibernate.show_sql", HIBERNATE_SHOW_SQL);
hibernateProperties.put("hibernate.hbm2ddl.auto", HIBERNATE_HBM2DDL_AUTO);
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
sessionFactory.setHibernateProperties(hibernateProperties);
sessionFactory.afterPropertiesSet(); // Used in Spring-boot 2.x for initializing the bean
SessionFactory sf = sessionFactory.getObject();
System.out.println("## getSessionFactory: " + sf);
return sf;
}