Replace getBean with #Autowired for Service - java

Here I have my main class with #Service called RegionsServiceImpl. I'm initializing it with ApplicationContext.getBean, but I want to use #Autowired. And when I do, #Autowired doesn't initialize it.
Main class:
package com.rebel.shop;
public class JpaRepoTest {
//ApplicationContext ctx;
#Autowired
RegionsServiceImpl regionsServiceImpl;
public JpaRepoTest() {
// ctx = new AnnotationConfigApplicationContext(DataConfig.class);
// regionsServiceImpl = ctx.getBean("regionsServiceImpl", RegionsServiceImpl.class);
}
public static void main(String[] args) {
JpaRepoTest jpaRepoTest = new JpaRepoTest();
jpaRepoTest.testService();
}
private void testService() {
System.out.println(regionsServiceImpl.findById(3l).getName());
}
}
My Service class:
package com.rebel.shop.persistence.jpa.service;
#Service
public class RegionsServiceImpl implements RegionsService {
#Resource
private RegionsRepository regionsRepository;
#Override
public Regions findById(long id) {
return regionsRepository.findOne(id);
}
}
It's interface:
package com.rebel.shop.persistence.jpa.service;
public interface RegionsService {
public Regions findById(long id);
}
Repo:
package com.rebel.shop.persistence.jpa.repository;
public interface RegionsRepository extends JpaRepository<Regions, Long> {
}
And Java Config For Spring:
package com.rebel.shop.persistence.jpa.config;
#Configuration
#EnableTransactionManagement
#PropertySource("classpath:app.properties")
#EnableJpaRepositories("com.rebel.shop.persistence.jpa.repository")
#ComponentScan("com.rebel.shop")
public class DataConfig {
private static final String PROP_DATABASE_DRIVER = "db.driver";
private static final String PROP_DATABASE_PASSWORD = "db.password";
private static final String PROP_DATABASE_URL = "db.url";
private static final String PROP_DATABASE_USERNAME = "db.username";
private static final String PROP_HIBERNATE_DIALECT = "db.hibernate.dialect";
private static final String PROP_HIBERNATE_SHOW_SQL = "db.hibernate.show_sql";
private static final String PROP_ENTITYMANAGER_PACKAGES_TO_SCAN = "db.entitymanager.packages.to.scan";
private static final String PROP_HIBERNATE_HBM2DDL_AUTO = "db.hibernate.hbm2ddl.auto";
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROP_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROP_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROP_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROP_DATABASE_PASSWORD));
return dataSource;
}
#Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory());
return txManager;
}
#Bean
public HibernateExceptionTranslator hibernateExceptionTranslator() {
return new HibernateExceptionTranslator();
}
#Bean
public EntityManagerFactory entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setShowSql(false);
vendorAdapter.setGenerateDdl(false);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.rebel.shop.persistence.entity");
factory.setDataSource(dataSource());
factory.afterPropertiesSet();
return factory.getObject();
}
// #Bean
// RegionsServiceImpl regionsServiceImpl() {
// return new RegionsServiceImpl();
// }
}
Thanks in advance!
UPD1:
Exception:
Exception in thread "main" java.lang.NullPointerException
at com.rebel.shop.JpaRepoTest.testService(JpaRepoTest.java:33)
at com.rebel.shop.JpaRepoTest.main(JpaRepoTest.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

You are not using the spring container, rather you are instantiating the object using new, hence no spring bean will be autowired, Modify your bean as below
package com.rebel.shop;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(DataConfig.class)
public class JpaRepoTest {
//ApplicationContext ctx;
#Autowired
RegionsServiceImpl regionsServiceImpl;
public JpaRepoTest() {
// ctx = new AnnotationConfigApplicationContext(DataConfig.class);
// regionsServiceImpl = ctx.getBean("regionsServiceImpl", RegionsServiceImpl.class);
}
#Test
public void mainMethod() {
testService();
}
private void testService() {
System.out.println(regionsServiceImpl.findById(3l).getName());
}
}

Related

Spring batch with two jobs FlatFileItemWriter and ClassifierCompositeItemWriter working together

Issue
I've to create a Spring batch project with two jobs that can be executed independently and together. Each job has the necessary code to read from database and to write using FlatFileItemWriter and ClassifierCompositeItemWriter. I've found that if I execute the Jobs independently (-Dspring.batch.job.names=schoolJob,-Dspring.batch.job.names=studentJob), the files are generated fine, but when I execute the Jobs together (-Dspring.batch.job.names=schoolJob,studentJob), the files of a Job only have the footer and the header. There seems to be something wrong but I can't find the cause.
Some code
Batch config, job and steps
#Configuration
#EnableBatchProcessing
#SuppressWarnings("rawtypes, unchecked")
public class MyJobConfiguration
{
#Autowired
private JobBuilderFactory jobBuilderFactory;
#Autowired
private StepBuilderFactory stepBuilderFactory;
#Autowired
private JdbcTemplate jdbcTemplate;
#Autowired
private ConfigurableApplicationContext applicationContext;
#Bean
public Step studentStep1() {
return stepBuilderFactory.get("calculateDistinctValuesAndRegisterStudentWriters")
.tasklet(new DynamicStudentWritersConfigurationTasklet(jdbcTemplate,
applicationContext))
.build();
}
#Bean
public Step schoolStep1() {
return stepBuilderFactory.get("calculateDistinctValuesAndRegisterSchoolWriters")
.tasklet(new DynamicSchoolWritersConfigurationTasklet(jdbcTemplate,
applicationContext))
.build();
}
#Bean
#JobScope
public Step studentStep2(StudentReader reader,
#Qualifier("studentClassfierItemWriter")
ClassifierCompositeItemWriter<Student> writer) {
SimpleStepBuilder<Student, Student> studentStep2 = stepBuilderFactory.get(
"readWriteStudents").<Student, Student>chunk(2).reader(reader).writer(writer);
Map<String, FlatFileItemWriter> beansOfType = applicationContext.getBeansOfType(
FlatFileItemWriter.class);
for (FlatFileItemWriter flatFileItemWriter : beansOfType.values())
{
studentStep2.stream(flatFileItemWriter);
}
return studentStep2.build();
}
#Bean
#JobScope
public Step schoolStep2(SchoolReader reader,
#Qualifier("schoolClassfierItemWriter")
ClassifierCompositeItemWriter<School> writer) {
SimpleStepBuilder<School, School> schoolStep2 = stepBuilderFactory.get("readWriteSchools")
.<School, School>chunk(2)
.reader(reader)
.writer(writer);
Map<String, FlatFileItemWriter> beansOfType = applicationContext.getBeansOfType(
FlatFileItemWriter.class);
for (FlatFileItemWriter flatFileItemWriter : beansOfType.values())
{
schoolStep2.stream(flatFileItemWriter);
}
return schoolStep2.build();
}
#Bean
public Job studentJob(Step studentStep1, Step studentStep2) {
return jobBuilderFactory.get("studentJob").start(studentStep1).next(studentStep2).build();
}
#Bean
public Job schoolJob(Step schoolStep1, Step schoolStep2) {
return jobBuilderFactory.get("schoolJob").start(schoolStep1).next(schoolStep2).build();
}
Data source configuration
#Configuration
class DatasourceConfig
{
#Bean
public DataSource dataSource()
{
String dbSchema = "/org/springframework/batch/core/schema-h2.sql";
String initData = "data.sql";
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
.addScript(dbSchema)
.addScript(initData)
.build();
}
}
Readers
#Component
class SchoolReader extends JdbcCursorItemReader<School>
{
#Autowired
private DataSource dataSource;
#Override
public void afterPropertiesSet() throws Exception
{
super.setName("schoolItemReader");
super.setDataSource(dataSource);
super.setSql("select * from school");
super.setRowMapper(new BeanPropertyRowMapper<>(School.class));
super.afterPropertiesSet();
}
}
#Component
class StudentReader extends JdbcCursorItemReader<Student>
{
#Autowired
private DataSource dataSource;
#Override
public void afterPropertiesSet() throws Exception
{
super.setName("studentItemReader");
super.setDataSource(dataSource);
super.setSql("select * from student");
super.setRowMapper(new BeanPropertyRowMapper<>(Student.class));
super.afterPropertiesSet();
}
}
Writers
#Configuration
public class SchoolWriter
{
#Autowired
private ConfigurableApplicationContext applicationContext;
#Bean(name = "schoolClassfierItemWriter")
#StepScope
public ClassifierCompositeItemWriter<School> itemWriter()
{
Map<String, FlatFileItemWriter> beansOfType = applicationContext.getBeansOfType(
FlatFileItemWriter.class);
Classifier<School, FlatFileItemWriter<School>> classifier = school -> beansOfType.get(
"school-group" + school.getGroupId() + "Writer");
return new ClassifierCompositeItemWriterBuilder().classifier(classifier).build();
}
}
#Configuration
public class StudentWriter
{
#Autowired
private ConfigurableApplicationContext applicationContext;
#Bean(name = "studentClassfierItemWriter")
#StepScope
public ClassifierCompositeItemWriter<Student> itemWriter()
{
Map<String, FlatFileItemWriter> beansOfType = applicationContext.getBeansOfType(
FlatFileItemWriter.class);
Classifier<Student, FlatFileItemWriter<Student>> classifier = student -> beansOfType.get(
"student-group" + student.getGroupId() + "Writer");
return new ClassifierCompositeItemWriterBuilder().classifier(classifier).build();
}
}
Tasklets
class DynamicSchoolWritersConfigurationTasklet implements Tasklet
{
private JdbcTemplate jdbcTemplate;
private ConfigurableApplicationContext applicationContext;
public DynamicSchoolWritersConfigurationTasklet(JdbcTemplate jdbcTemplate,
ConfigurableApplicationContext applicationContext)
{
this.jdbcTemplate = jdbcTemplate;
this.applicationContext = applicationContext;
}
#Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext)
{
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
String sql = "select distinct(groupId) from school";
List<Integer> groups = jdbcTemplate.queryForList(sql, Integer.class);
for (Integer group : groups)
{
String name = "school-group" + group + "Writer";
//#f:off
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.addPropertyValue("name", name);
propertyValues.addPropertyValue("lineAggregator", new PassThroughLineAggregator<>());
propertyValues.addPropertyValue("resource", new FileSystemResource("school-" + group + ".txt"));
propertyValues.addPropertyValue("headerCallback", (FlatFileHeaderCallback) writer -> writer.write("header-school"));
propertyValues.addPropertyValue("footerCallback", (FlatFileFooterCallback) writer -> writer.write("footer-school"));
//#f:on
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClassName(FlatFileItemWriter.class.getName());
beanDefinition.setPropertyValues(propertyValues);
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
registry.registerBeanDefinition(name, beanDefinition);
}
return RepeatStatus.FINISHED;
}
}
class DynamicStudentWritersConfigurationTasklet implements Tasklet
{
private JdbcTemplate jdbcTemplate;
private ConfigurableApplicationContext applicationContext;
public DynamicStudentWritersConfigurationTasklet(JdbcTemplate jdbcTemplate,
ConfigurableApplicationContext applicationContext)
{
this.jdbcTemplate = jdbcTemplate;
this.applicationContext = applicationContext;
}
#Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext)
{
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
String sql = "select distinct(groupId) from student";
List<Integer> groups = jdbcTemplate.queryForList(sql, Integer.class);
for (Integer group : groups)
{
String name = "student-group" + group + "Writer";
//#f:off
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.addPropertyValue("name", name);
propertyValues.addPropertyValue("lineAggregator", new PassThroughLineAggregator<>());
propertyValues.addPropertyValue("resource", new FileSystemResource("student-" + group + ".txt"));
propertyValues.addPropertyValue("headerCallback", (FlatFileHeaderCallback) writer -> writer.write("header-student"));
propertyValues.addPropertyValue("footerCallback", (FlatFileFooterCallback) writer -> writer.write("footer-student"));
//#f:on
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClassName(FlatFileItemWriter.class.getName());
beanDefinition.setPropertyValues(propertyValues);
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
registry.registerBeanDefinition(name, beanDefinition);
}
return RepeatStatus.FINISHED;
}
}
DAO
#Getter
#Setter
#ToString
#NoArgsConstructor
#AllArgsConstructor
public class School
{
private int id;
private String name;
private int groupId;
}
#Getter
#Setter
#ToString
#NoArgsConstructor
#AllArgsConstructor
public class Student
{
private int id;
private String name;
private int groupId;
}
This is similar to https://stackoverflow.com/a/67635289/5019386. I think you need to make your dynamic item writers step-scoped as well, something like:
propertyValues.addPropertyValue("scope", "step");
Please note that I did not try that. That said, I would really recommend making your app do one thing and do it well, ie isolate job definitions and package/run each job separately.

Could not `Autowired`, no bean of `SessionFactory` type found

I am trying to run test for add data to database using Spring Hibernate. I assigned #Bean for function getSessionFactory in HibernateConfig.java, but when I call again in DAOImp file, I get error Could not autowire. No beans of 'SessionFactory' type found.
HibernateConfig.java
#Configuration
#EnableTransactionManagement
#ComponentScan(basePackages = {"com.huyvt.onlineshopping.dto"})
public class HibernateConfig {
private final static String DATABASE_URL = "jdbc:mysql://localhost:3308/onlineshopping?serverTimezone=UTC";
private final static String DATABASE_DRIVER = "com.mysql.jdbc.Driver";
private final static String DATABASE_DIALECT = "org.hibernate.dialect.H2Dialect";
private final static String DATABASE_USER = "root";
private final static String DATABASE_PASSWORD = "";
#Bean
public DataSource getDataSource(){
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(DATABASE_DRIVER);
dataSource.setUrl(DATABASE_URL);
dataSource.setUsername(DATABASE_USER);
dataSource.setPassword(DATABASE_PASSWORD);
return dataSource;
}
#Bean
public SessionFactory getSessionFactory(DataSource dataSource){
LocalSessionFactoryBuilder sessionFactoryBuilder = new LocalSessionFactoryBuilder(dataSource);
sessionFactoryBuilder.addProperties(getHibernateProperties());
return sessionFactoryBuilder.buildSessionFactory();
}
private Properties getHibernateProperties(){
Properties properties = new Properties();
properties.put("hibernate.dialect", DATABASE_DIALECT);
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.format_sql", "true");
return properties;
}
#Bean
public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory){
return new HibernateTransactionManager(sessionFactory);
}
}
CategoryDAOImp.java
#Repository("categoryDAO")
public class CategoryDAOImp implements CategoryDAO {
#Autowired
private SessionFactory sessionFactory;
#Override
#Transactional
public boolean add(Category category) {
try {
//add category to db
System.out.println(category.toString());
sessionFactory.getCurrentSession().persist(category);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
How can I fix it?
In which package is your HibernateConfig class found ?
This
#Bean
public SessionFactory getSessionFactory(DataSource dataSource){
is not being executed.
To confirm, you could do a 'System.out.println("XXX")' like so:
#Bean
public SessionFactory getSessionFactory(DataSource dataSource){
System.out.println("sessionFactory bean is getting created")
...
}
and check if you can see it in your console when you launch your application.
To ensure that it is being picked up, the easiest way is to ensure that you have a #ComponentScan in your root class found here com.huyvt.onlineshopping.
#ComponentScan without arguments tells Spring to scan the current
package and all of its sub-packages.
If you are using Spring Boot, this is automatically added for you when you are using #SpringBootApplication.
Also, in your main method, you can check your created beans like so:
private static ApplicationContext applicationContext;
public static void main(String[] args) {
applicationContext =
new AnnotationConfigApplicationContext(SpringComponentScanApp.class);
for (String beanName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanName);
}
}

Configuration Properties by #Autowired is null in Spring Boot

I have a properties class
#ConfigurationProperties(prefix = ShiroProperties.SHIRO_PREFIX)
public class ShiroProperties {
public static final String SHIRO_PREFIX = "shiro";
private String urlLogin;
private String urlSuccessed;
and a Configuration class
#Configuration
#EnableConfigurationProperties({ ShiroProperties.class })
public class ShiroConfig implements ApplicationContextAware {
ApplicationContext applicationContext;
#Autowired
private ShiroProperties shiroProperties ;
shiroProperties is null, but i can find it value in ShiroConfig used
applicationContext.getBean(ShiroProperties.class)
my Application class:
#SpringBootApplication
public class Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Bootstrap.class, args);
}
}
So weird, i can run success with similar code in other project, but this.
I met this same issue as #Dean said,I had done is put the LifecycleBeanPostProcessor bean is another configure class ,and configure other Shiro in another configuration class ,see below example:
#Configuration
public class ShiroLifecycleBeanPostProcessorConfig {
/**
*
*
* #return
*/
#Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
}
The main Shiro Configuration class:
#Configuration
#AutoConfigureAfter(value = ShiroLifecycleBeanPostProcessorConfig.class)
public class ShiroConfiguration {
public static final String cacheFile = "encache.xml";
private static final String active_cache_name = "activeSessionCache";
#Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
*
*
* #throws UnknownHostException
*/
#Bean(name = "shiroFilter")
#ConditionalOnMissingBean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager)
throws UnknownHostException {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl(ShiroSecurityUrls.LOGIN_PAGE);
// shiroFilterFactoryBean.setSuccessUrl(ShiroSecurityUrls.LOGIN_SUCCESS_URL);
shiroFilterFactoryBean.setUnauthorizedUrl("/error");
Map<String, Filter> filters = new LinkedHashMap<String, Filter>();
LogoutFilter logoutFilter = new LogoutFilter();
logoutFilter.setRedirectUrl(ShiroSecurityUrls.LOGIN_PAGE);
filters.put(DefaultFilter.logout.name(), logoutFilter);
shiroFilterFactoryBean.setFilters(filters);
Map<String, String> filterChainDefinitionManager = new LinkedHashMap<String, String>();
filterChainDefinitionManager.put("/static/**", DefaultFilter.anon.name());
filterChainDefinitionManager.put("/node_modules/**", DefaultFilter.anon.name());
filterChainDefinitionManager.put("/pages/**", DefaultFilter.anon.name());
filterChainDefinitionManager.put(ShiroSecurityUrls.LOGIN_PAGE, DefaultFilter.anon.name());
filterChainDefinitionManager.put(ShiroSecurityUrls.LOGOUT_URL, DefaultFilter.logout.name());
filterChainDefinitionManager.put(ShiroSecurityUrls.REGISTER_PROCESS_URL, DefaultFilter.anon.name());
filterChainDefinitionManager.put("/**", DefaultFilter.user.name());
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager);
return shiroFilterFactoryBean;
}
/**
*
*
* #throws UnknownHostException
*/
#Bean(name = "securityManager")
#DependsOn(value = { "ehCacheManager", "rememberMeManager", "sessionManager", "credentialsMatcher" })
public DefaultWebSecurityManager securityManager(EhCacheManager ehCacheManager, RememberMeManager rememberMeManager,
SessionManager sessionManager, CredentialsMatcher credentialsMatcher) throws UnknownHostException {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 1. Cache Support
securityManager.setCacheManager(ehCacheManager);
// 2. Session Support,inject the cacheManager from securitymanager
securityManager.setSessionManager(sessionManager);
// 3. Rememberme Support
securityManager.setRememberMeManager(rememberMeManager);
// 4. JDBC,LDAP Realm implements
Collection<Realm> authorizingRealms = Lists.newArrayList(shiroDatabaseRealm(credentialsMatcher),
shiroActiveDirectoryRealm(credentialsMatcher));
securityManager.setRealms(authorizingRealms); // inject the cacheManager
// from securitymanager
if (securityManager.getAuthenticator() instanceof ModularRealmAuthenticator) {
ModularRealmAuthenticator modularRealmAuthenticator = (ModularRealmAuthenticator) securityManager
.getAuthenticator();
modularRealmAuthenticator.setAuthenticationStrategy(new FirstSuccessfulStrategy());
}
return securityManager;
}
}
Hope this code helps you ,thanks.
This being another configuration class for your application should be decorated with #Configuration annotation to enable a bean creation and injection into the context for wiring from another classes.
In common, AutowiredAnnotationBeanPostProcessor set such property annotationed by #Autowired in the phase when Spring load FactoryBean classes. If the following factory beans:
ApplicationContextAwareProcessor
ApplicationListenerDetector
ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor
PostProcessorRegistrationDelegate$BeanPostProcessorChecker
CommonAnnotationBeanPostProcessor
refer your config bean, your bean will not be autowired properties after creation due to AutowiredAnnotationBeanPostProcessor is not loaded.
For example, properties is null and throw NullPointerException
#Component
public class BeanFactoryTest {
#Autowired
private IdGenProperties properties;
#Bean
public SnowflakeServer snowflakeServer() {
System.out.println(properties.getBaseUrl());
return null;
}
#Bean(name = "conversionService")
public ConversionServiceFactoryBean getConversionService() {
ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
Set<Converter> converters = new HashSet<>();
converters.add(new StringToDateConverter());
bean.setConverters(converters);
return bean;
}
public static class StringToDateConverter implements Converter<String, Date>
{
public Date convert(String source) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
return sdf.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
}
Try with adding #Component in your ShiroProperties.class
#Component
#ConfigurationProperties(prefix = ShiroProperties.SHIRO_PREFIX)
public class ShiroProperties {
public static final String SHIRO_PREFIX = "shiro";
private String urlLogin;
private String urlSuccessed;
}

Use of Transactional annotation in Spring data with Hibernate

I'm using Spring data and Hibernate to manage my database. I have for example repository class like this:
public interface NotificationHasUserRepository extends JpaRepository<NotificationHasUser, NotificationHasUserKeys> {
List<NotificationHasUser> findByPkUserAndIsReadFalse(User user);
#Modifying
#Query("UPDATE NotificationHasUser u SET u.isRead=true WHERE u.pk.user = ?1")
void setNotificationsAsRead(User user);
void deleteByPkUserAndPkNotification(User user, Notification notification);
List<NotificationHasUser> findByPkUser(User user);
#Query("select count(u)>0 from NotificationHasUser u WHERE u.pk.notification = ?1")
boolean existsByPkNotification(Notification notification);
}
I inject this class in my service class:
#Service
#Transactional
public class NotificationHasUserServicesImpl implements NotificationHasUserServices {
#Resource
private NotificationHasUserRepository notificationHasUserRepository;
#Override
public NotificationHasUser create(NotificationHasUser notificationHasUser) {
return notificationHasUserRepository.save(notificationHasUser);
}
#Override
public NotificationHasUser findById(NotificationHasUserKeys id) {
return notificationHasUserRepository.findOne(id);
}
#Override
public boolean exists(NotificationHasUserKeys id) {
return notificationHasUserRepository.exists(id);
}
#Override
public List<NotificationHasUser> findByPkUserAndIsReadFalse(User user) {
return notificationHasUserRepository.findByPkUserAndIsReadFalse(user);
}
#Override
public void setNotificationsAsRead(User user) {
notificationHasUserRepository.setNotificationsAsRead(user);
}
#Override
public List<NotificationHasUser> getNotifications(User user) {
return notificationHasUserRepository.findByPkUser(user);
}
#Override
public void deleteSelectedNotification(User user, Notification notification) {
notificationHasUserRepository.deleteByPkUserAndPkNotification(user, notification);
}
#Override
public boolean existsByPkNotification(Notification notification) {
return notificationHasUserRepository.existsByPkNotification(notification);
}
}
I'm using #Transaction on the service class but I receive exception when I call delete or update query
.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
If I add #Transcational on each method in repository class all work fine, is it not possible to add at service level?Thanks
This is my spring configuration:
#EnableAsync
#EnableWebMvc
#Configuration
#PropertySource(value = { "classpath:application.properties" })
#ComponentScan({ "com.*" })
#EnableTransactionManagement
#Import({ SecurityConfig.class, SpringMvcInitializer.class})
#EnableJpaRepositories("com.repository")
public class AppConfig extends WebMvcConfigurerAdapter implements AsyncConfigurer{
#Autowired
private Environment env;
#Autowired
private MyAsyncUncaughtExceptionHandler myAsyncUncaughtExceptionHandler;
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
// private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
/**
* This and the next methods are used to avoid exception while jackson mapping the entity, so fields are setted with null value
* unless use Hibernate.initialize
* #return
*/
public MappingJackson2HttpMessageConverter jacksonMessageConverter(){
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = new ObjectMapper();
//Registering Hibernate4Module to support lazy objects
mapper.registerModule(new Hibernate4Module());
messageConverter.setObjectMapper(mapper);
return messageConverter;
}
/**
* Used for spring security
* #return
*/
#Bean
public SpringSecurityDialect springSecurityDialect() {
SpringSecurityDialect dialect = new SpringSecurityDialect();
return dialect;
}
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//Here we add our custom-configured HttpMessageConverter
converters.add(jacksonMessageConverter());
super.configureMessageConverters(converters);
}
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
// properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
properties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
properties.put("hibernate.enable_lazy_load_no_trans",true);
return properties;
}
#Bean(name = "dataSource")
public BasicDataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
ds.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
ds.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
ds.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return ds;
}
#Bean
public ServletContextTemplateResolver TemplateResolver(){
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/templates/pages/");
resolver.setSuffix(".html");
resolver.setTemplateMode("LEGACYHTML5");
resolver.setCacheable(false);
return resolver;
/*ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
return resolver;*/
}
#Bean
public SpringTemplateEngine templateEngine(){
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(TemplateResolver());
templateEngine.addDialect(springSecurityDialect());
return templateEngine;
}
#Bean
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setOrder(1);
resolver.setViewNames(new String[]{"*", "js/*", "template/*"});
return resolver;
}
/**
* Register multipartResolver for file upload
* #return
*/
#Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver=new CommonsMultipartResolver();
resolver.setDefaultEncoding("utf-8");
return resolver;
}
/**
* Allow use of bootstrap
*/
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("/static/");
}
/**
* Allow use of JPA
*/
#Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setPackagesToScan(env.
getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
entityManagerFactoryBean.setJpaProperties(getHibernateProperties());
return entityManagerFactoryBean;
}
/**
* Async exception configuration
*/
#Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(10);
executor.initialize();
return executor;
}
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return myAsyncUncaughtExceptionHandler;
}
}

Vaadin + Spring Integration: Null Pointer exception

I have a Vaadin web application with UI class like this:
#SuppressWarnings("serial")
#Theme("mytheme")
public class LogsUI extends UI {
LogsView logsViewer = new LogsView();
#WebServlet(value = "/*", asyncSupported = true)
#VaadinServletConfiguration(productionMode = false, ui = LogsUI.class)
public static class Servlet extends VaadinServlet {
}
#Override
protected void init(VaadinRequest request) {
Panel panel = new Panel();
panel.setContent(logsViewer);
panel.setSizeFull();
setContent(panel);
}
}
As u can see i add use setContent to add LogsView class which is a view - it is a fragment of declaration:
#SuppressWarnings("serial")
public class LogsView extends CustomComponent implements View {
//some variables, buttons, components etc
ProcessDao processDao;
//sample method
void sampleMethod(){
processDao = new ProcesDao;
processDao.getAllprocesses(); //just sample, no matter about logic
}
}
My ProcessDao class:
public class ProcessDao {
#Autowired
ApplicationConfiguration applicationConfiguration;
public ProcessDao() {
}
public List<ProcessEntity> getAllProcess(){
System.out.println("TEST:" + applicationConfiguration);
//entity manager and other stuffs
return processList;
}
}
As u can see i did System.out.println() to check if im getting applicationConfiguration object. Im getting null. This is main problem.
this is my ApplicationConfiguration class:
#Configuration
#EnableTransactionManagement
#ComponentScan(basePackages = {"com.sample.project"})
#PropertySource({"classpath:jpa.postgresql.properties", "classpath:hibernate.properties"})
#EnableJpaRepositories(basePackages = {"com.sample.project.repo"})
public class ApplicationConfiguration extends WebMvcConfigurerAdapter {
#Value("${javax.persistence.jdbc.driver}")
private String driverClassName;
#Value("${javax.persistence.jdbc.url}")
private String databaseUrl;
#Value("${javax.persistence.jdbc.user}")
private String databaseUser;
#Value("${javax.persistence.jdbc.password}")
private String databasePassword;
#Value("${hibernate.dialect}")
private String dialect;
#Value("${hibernate.show_sql}")
private boolean showSQL;
#Value("${hibernate.hbm2ddl.auto}")
private String hbm2ddlAuto;
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
#Bean
#PersistenceContext
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setJpaProperties(hibernateJPAProperties());
entityManagerFactoryBean.setPackagesToScan("com.sample.project");
return entityManagerFactoryBean;
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(databaseUrl);
dataSource.setUsername(databaseUser);
dataSource.setPassword(databasePassword);
return dataSource;
}
public Properties hibernateJPAProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", dialect);
properties.put("hibernate.show_sql", showSQL);
properties.put("hibernate.hbm2ddl.auto", hbm2ddlAuto);
return properties;
}
#Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
#Bean
public FinancialProcessEntityDao financialProcessEntityDao() {
FinancialProcessEntityDao dao = new FinancialProcessEntityDao();
return dao;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
Am i something missing? How to properly integrate my Vaadin app with Spring?
You should try this:
processDao = WebApplicationContextUtils.getRequiredWebApplicationContext(
VaadinServlet.getCurrent().getServletContext()).getBean(IProcessDao.class);
You can find some description here: link

Categories

Resources