I use spring version 5.0.1, hibernate version 5.2.12.
When I call getHibernateTemplate (), I get null
what am I doing wrong?
Dao confif:
#PropertySource(value = {"classpath:hibernate.properties"})
#ComponentScan("ru.bochkarev.hmcs.dao")
#EnableTransactionManagement
#Configuration
public class DaoConfig {
#Autowired
private Environment environment;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("hibernate.connection.driver_class"));
dataSource.setUrl(environment.getRequiredProperty("hibernate.connection.url"));
dataSource.setUsername(environment.getRequiredProperty("hibernate.connection.username"));
dataSource.setPassword(environment.getRequiredProperty("hibernate.connection.password"));
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
return properties;
}
#Bean
public SessionFactory sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("ru.bochkarev.hmcs.model");
sessionFactory.setHibernateProperties(hibernateProperties());
try {
sessionFactory.afterPropertiesSet();
} catch (IOException e) {
e.printStackTrace();
}
return sessionFactory.getObject();
}
#Bean
public HibernateTransactionManager hibernateTransactionManager(){
return new HibernateTransactionManager(sessionFactory());
}
#Bean
public HibernateTemplate hibernateTemplate() {
return new HibernateTemplate(sessionFactory());
}
}
.................................................................
Implement dao:
#Transactional
#Repository
public class DaoTest extends HibernateDaoSupport {
public void save(TestModel testModel) {
getHibernateTemplate().saveOrUpdate(testModel);
}
}
When I call getHibernateTemplate (), I get null
Try below code for your DAO class and let us know if it works.
#Transactional
#Repository
public class DaoTest {
#Autowired
private HibernateTemplate hibernateTemplate;
public void save(TestModel testModel) {
getHibernateTemplate().saveOrUpdate(testModel);
}
}
Related
I've been reading Spring Boot tutorials, most of the MVC patterns are implemented based on
1) Dao interface
2) Dao Interface Implementation
3) Service interface for persistence
4) Service implementation
I think this is the good practice and I was working it. Now I try to use JpaRepository which helps to implement easily and efficiently. The configuration of my project is
Configuration class
#Configuration
#PropertySource(value = { "classpath:application.properties" })
#EnableJpaRepositories(value={"com.dept.dao"})
public class ApplicationContextConfig {
#Autowired
private Environment environment;
#Bean(name = "dataSource")
public DataSource getDataSource() {
//DataSource connections
}
private Properties getHibernateProperties() {
//Hibernate properties
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(getDataSource());
sessionFactory.setPackagesToScan(new String[] { "com.dept.model" });
sessionFactory.setHibernateProperties(getHibernateProperties());
return sessionFactory;
}
#Autowired
#Bean(name = "transactionManager")
public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);
return transactionManager;
}
#Primary
#Bean(name="entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws ClassNotFoundException {
final LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(getDataSource());
// mention packae scan your classes annotated as #Entity
entityManagerFactoryBean.setPackagesToScan(new String[] { "com.dept.model" });
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setShowSql(true);
entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
entityManagerFactoryBean.setJpaProperties(getHibernateProperties());
entityManagerFactoryBean.afterPropertiesSet();
entityManagerFactoryBean.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
return entityManagerFactoryBean;
}
#Primary
#Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
try {
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
transactionManager.setDataSource(getDataSource());
transactionManager.setJpaDialect(new HibernateJpaDialect());
transactionManager.setJpaProperties(getHibernateProperties());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
#Bean
public HibernateExceptionTranslator hibernateExceptionTranslator() {
return new HibernateExceptionTranslator();
}
#Bean
public JpaVendorAdapter japAdapter(){
return new HibernateJpaVendorAdapter();
}
}
Example I need to save this object in database. So I implemented methods
Doa interface
public interface DepartmentDao extends JpaRepository<Department, Integer>{
}
I'm stuck how to implement Dao implementation, I used like this
Dao Implementation
#Repository
public class DepartmentDaoImpl implements DepartmentDao {
#Autowired
private SessionFactory sessionFactory;
// All other overridden methods
#Override
public <S extends Department> S save(S entity) {
return (S) sessionFactory.getCurrentSession().save(entity);
}
}
Service interface
public interface DepartmentService {
// Other all necessary methods
public <S extends Department> S save(S entity);
}
Service Implementation
#Service
public class DepartmentServiceImpl implements DepartmentService{
#Autowired
DepartmentDao departmentDao;
#Override
#Transactional
public <S extends Department> S save(S entity) {
return departmentDao.save(entity);
}
}
Controller class
#RequestMapping(value = "/save", method = RequestMethod.POST)
public ModelAndView saveDepartment(#Valid #ModelAttribute("departmentForm") Department department) {
departmentService.save(department); //departmen already autowired
return new ModelAndView("redirect:/department/list");
}
I tried to save this object in database, but no transaction happened. There were no errors also. Since I'm new to Spring Boot, I confused myself how to use jparepository. I developed this by using online reference and spent more time.
My project is using Spring MVC4, Hibernate 5. I have configured hibernate transaction with Advice Interceptor, but it does not rollback as I would like. Please help me, what is the problem with my configuration?
All my code is as below:
1. Hibernate config:
#Configuration
#EnableTransactionManagement
public class DataSourceConfiguration {
#Autowired
private Environment env;
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(
new String[] {env.getProperty("spring.hibernate.packagesToScan")});
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
return dataSource;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);
return txManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
Spring Advice Interceptor:
#Aspect
#Configuration
public class TxAdviceInterceptor {
private static final String TX_METHOD_NAME = "*";
#Value(value = "${tx-advice.timeout:-1}")
private Integer txMethodTimeout = -1;
private static final String AOP_POINTCUT_EXPRESSION =
"execution(* com.ptg.service..*.*(..))";
#Autowired
private PlatformTransactionManager transactionManager;
#Bean
public TransactionInterceptor txAdvice() {
MatchAlwaysTransactionAttributeSource source = new MatchAlwaysTransactionAttributeSource();
RuleBasedTransactionAttribute transactionAttribute = new RuleBasedTransactionAttribute();
transactionAttribute.setName(TX_METHOD_NAME);
transactionAttribute.setRollbackRules(
Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
transactionAttribute.setTimeout(txMethodTimeout);
source.setTransactionAttribute(transactionAttribute);
return new TransactionInterceptor(transactionManager, source);
}
#Bean
public Advisor txAdviceAdvisor() {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
return new DefaultPointcutAdvisor(pointcut, txAdvice());
}
}
DAO:
#Repository
public abstract class GenericDaoImpl{
#Autowired
private SessionFactory sessionFactory;
#Override
public void S save(S entity) {
sessionFactory.save(entity);
}
}
DaoImpl:
#Repository
public class TagDaoImpl extends GenericDaoImpl{
}
#Repository
public class PostDaoImpl extends GenericDaoImpl{
}
Service:
#Service
public class PostServiceImpl{
#Autowired
private PostDao postDao;
#Autowired
private TagDao tagDao;
public void merge(Post post){
tagDao.save();
postDao.save();
}
}
As code above, I would like if postDao.save is error, tagDao is also rollback.
I have found the problem. My configuration is not wrong.
The problem is "Only unchecked exceptions (that is, subclasses of java.lang.RuntimeException) are rollbacked by default. For the case, a checked exception is thrown, the transaction will be committed".
I have test my code with NullPointerException error, therefore Transaction is not rollbacked.
Refer: https://www.catalysts.cc/wissenswertes/spring-transactional-rollback-on-checked-exceptions/
have you tried #Transactional annotation?
I have a JavaConfig configurated Spring Batch job. The main job configuration file is CrawlerJobConfiguration. Before now, I have all the configuration (infrastructure, autowired beans, etc) in this class and it works fine. So I decided to separate the job configuration from autowired beans and infracstruture beans configuration and create another 2 configuration classes Beans and MysqlInfrastructureConfiguration.
But now I am having problems to run my job. I'm receiving a NullPointerException when the application try to use autowired fields indicating that the autowired is not working.
I put a breakpoint in the methods that create autowired beans to make sure that they are being called and really are, so I cannot realize what can be the problem.
java.lang.NullPointerException: null
at br.com.alexpfx.supermarket.batch.tasklet.StartCrawlerTasklet.execute(StartCrawlerTasklet.java:27) ~[classes/:na]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406) ~[spring-batch-core-3.0.6.RELEASE.jar:3.0.6.RELEASE]
Main job configuration class:
#Configuration
#EnableBatchProcessing
public class CrawlerJobConfiguration {
#Autowired
private InfrastructureConfiguration infrastructureConfiguration;
#Autowired
private StepBuilderFactory steps;
#Autowired
Environment environment;
#Bean
public Job job(JobBuilderFactory jobs) {
Job theJob = jobs.get("job").start(crawlerStep()).next(processProductStep()).build();
((AbstractJob) theJob).setRestartable(true);
return theJob;
}
#Bean
public Step crawlerStep() {
TaskletStep crawlerStep = steps.get("crawlerStep").tasklet(crawlerTasklet()).build();
crawlerStep.setAllowStartIfComplete(true);
return crawlerStep;
}
#Bean
public Step processProductStep() {
TaskletStep processProductStep = steps.get("processProductStep")
.<TransferObject, Product>chunk(10)
.reader(reader())
.processor(processor())
.writer(writer())
.build();
processProductStep.setAllowStartIfComplete(true);
return processProductStep;
}
private Tasklet crawlerTasklet() {
return new StartCrawlerTasklet();
}
private ItemProcessor<TransferObject, Product> processor() {
return new ProductProcessor();
}
private ItemReader<TransferObject> reader() {
return new ProductItemReader();
}
private ItemWriter<Product> writer() {
return new HibernateProductsItemWriter();
}
}
Beans configuration class:
#Configuration
#EnableBatchProcessing
public class Beans {
#Bean
public Crawler crawler() {
return new RibeiraoCrawler(new UserAgentFactory());
}
#Bean
public ProductBo productBo() {
return new ProductBoImpl();
}
#Bean
public ProductDao productDao() {
return new ProductDaoImpl();
}
#Bean
public CrawlerListener listener() {
CrawlerListener listener = new RibeiraoListener();
return listener;
}
#Bean
public ProductList getProductList() {
return new ProductList();
}
}
MysqlInfrastructureConfiguration:
#Configuration
#EnableBatchProcessing
#PropertySource("classpath:database.properties")
#EnableJpaRepositories(basePackages = {"br.com.alexpfx.supermarket.domain"})
public class MysqlInfrastructureConfiguration implements InfrastructureConfiguration {
#Value("${jdbc.url}")
String url;
#Value("${jdbc.driverClassName}")
String driverClassName;
#Value("${jdbc.username}")
String username;
#Value("${jdbc.password}")
String password;
#Bean
#Override
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
#Bean
#Override
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory());
transactionManager.setDataSource(getDataSource());
return transactionManager;
}
#Bean
#Override
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(getDataSource());
em.setPackagesToScan(new String[]{"br.com.alexpfx.supermarket.domain"});
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalJpaProperties());
em.afterPropertiesSet();
return em.getObject();
}
private Properties additionalJpaProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
properties.setProperty("hibernate.show_sql", "true");
properties.setProperty("current_session_context_class", "thread");
return properties;
}
}
tasklet:
public class StartCrawlerTasklet implements Tasklet {
#Autowired
private Crawler crawler;
#Autowired
private CrawlerListener listener;
#Override
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
crawler.setListener(listener);
crawler.setStopCondition(new TimeLimitStopCondition(1, TimeUnit.MINUTES));
crawler.crawl();
return RepeatStatus.FINISHED;
}
}
StartCrawlerTasklet use the autowired annotation, so it should be a bean as well. So change your code :
private Tasklet crawlerTasklet() {
return new StartCrawlerTasklet();
}
to a bean definition:
#Bean
public Tasklet crawlerTasklet() {
return new StartCrawlerTasklet();
}
We are configuring Hibernate using java, here is our code to configure hibernate.
#Configuration
#EnableTransactionManagement
#ComponentScan({ "org.npcc.ccms.config" })
#PropertySource(value = { "classpath:application.properties" })
public class HibernateConfiguration {
final static Logger logger = LogManager.getLogger(HibernateConfiguration.class);
#Autowired
private Environment environment;
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "org.npcc.ccms.model" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean(destroyMethod="")
public DataSource dataSource() {
JndiTemplate jndi = new JndiTemplate();
DataSource dataSource = null;
try {
dataSource = (DataSource) jndi.lookup(environment.getRequiredProperty("datasource"));
} catch (NamingException e) {
logger.error("NamingException for java:comp/env/jdbc/ccms_cp1_orcl", e);
}
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
return properties;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(s);
return txManager;
}
}
My question is how can configure another datasource within same hibernate configuration class? I found solution here but using xml configuration, how this works using java configuration? Thanks in advance.
You will need two different beans annotated as follows:
#Bean(name="SessionFactory")
public SessionFactory sessionFactory() {
}
and:
#Bean(name="OtherSessionFactory")
public SessionFactory otherSessionFactory() {
}
And two datasources configured appropriately.
Then when you want to use the other SessionFactory you just need:
#Autowired
#Qualifier("SessionFactory")
SessionFactory sessionFactory
or
#Autowired
#Qualifier("OtherSessionFactory")
SessionFactory sessionFactory
I try to setup a project with spring-test using TestNg in Maven. The code is like:
#ContextConfiguration(classes={WebMvcTestConfig.class})
public class MyResourceParserTest extends AbstractTestNGSpringContextTests {
#BeforeMethod
public void setup() throws Exception {
}
A WebMvcTestConfig class simply defined a bean:
#Configuration
#ComponentScan(basePackages={"com.test.myapp.model"})
#EnableTransactionManagement
public class WebMvcTestConfig {
private static final String relativeConfigURI = "\\MyAppSpringConfig\\";
private static final String userHomeURI = System.getProperty("user.home");
private static final String jdbcPropertiesFileName = "jdbc.properties";
private static final String hibernatePropertiesFileName = "hibernate.properties";
#Bean
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
propertySourcesPlaceholderConfigurer.setLocation(new FileSystemResource(userHomeURI + relativeConfigURI + jdbcPropertiesFileName));
return propertySourcesPlaceholderConfigurer;
}
#Bean
public DataSource dataSource(
#Value("${jdbc.driverClassName}") String driverClass,
#Value("${jdbc.url}") String jdbcUrl,
#Value("${jdbc.username}") String username,
#Value("${jdbc.password}") String password) {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUrl(jdbcUrl);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
#Bean
public LocalSessionFactoryBean localSessionFactoryBean() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource("", "", "", ""));
sessionFactory.setPackagesToScan("com.test.myapp.model.domain");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public Properties hibernateProperties() {
Properties hibernateProperties = new Properties();
try {
hibernateProperties.load(new FileInputStream(userHomeURI + relativeConfigURI + hibernatePropertiesFileName));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
return hibernateProperties;
}
#Bean
public PlatformTransactionManager platformTransactionManager() {
return new HibernateTransactionManager(localSessionFactoryBean().getObject());
}
}
I got error for Failed to load ApplicationContext when running mvn test from command line:
java.lang.IllegalStateException: Failed to load ApplicationContext
Can you help me?
3 things I notice from your configuration.
Your loading of configuration files is strange, use Spring for that instead of rolling your own. Simply use #PropertySource for that.
The propertySourcesPlaceholderConfigurer() must be static
Your call to datasource will lead to an invalid datasource configuration.
Try the following configuration class.
#Configuration
#ComponentScan(basePackages={"com.test.myapp.model"})
#EnableTransactionManagement
#PropertySource({"${user.home}/MyAppSpringConfig/jdbc.properties","${user.home}/MyAppSpringConfig/hibernate.properties"}
public class WebMvcTestConfig {
#Autowired
private Environment env;
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new new PropertySourcesPlaceholderConfigurer();
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getRequiredProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("env.username", ""));
dataSource.setPassword(env.getProperty("env.password", ""));
return dataSource;
}
#Bean
public LocalSessionFactoryBean localSessionFactoryBean() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("com.test.myapp.model.domain");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public Properties hibernateProperties() {
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
// Other properties
return hibernateProperties;
}
#Bean
public PlatformTransactionManager platformTransactionManager() {
return new HibernateTransactionManager(localSessionFactoryBean().getObject());
}
}