Using <context:component-scan base-package /> in annotation based configuration - java

I have gone through different resources but still I am not getting my work done. Here is my Spring annotation based configuration :-
#Configuration
#EnableTransactionManagement
#PropertySource({ "classpath:persistence-mysql.properties" })
#ComponentScan({ "org.baeldung.persistence" })
public class PersistenceJPAConfig {
#Autowired
private Environment env;
public PersistenceJPAConfig() {
super();
}
// beans
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" });
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
#Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
return dataSource;
}
#Bean
public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
final Properties additionalProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
// hibernateProperties.setProperty("hibernate.globally_quoted_identifiers",
// "true");
return hibernateProperties;
}
}
I have my controller class in org.baeldung.persistence.controller package and denoted #Controller at the top of the class. Still I am getting 404 error when I access the URL /products. Here is my controller class
#Controller
public class ProductViewController {
#RequestMapping(value = "/products", method = RequestMethod.POST)
public String create(#ModelAttribute("product") final Product product) {
final ProductServiceImpl productServiceImpl = new ProductServiceImpl();
if (productServiceImpl.create(product)) {
return "Product with product name : " + product.getProduct_name() + "Has been created";
} else {
return "Error while creating the product record";
}
}

Sinnce your controller class is in org.baeldung.persistence.controller package, you have to scan components in this package
#ComponentScan({ "org.baeldung.persistence.controller" })
you will also need to add #EnableWebMvc in PersistenceJPAConfig class
#EnableWebMvc

Related

Java Bean not found in configuration with multiple module

I having a configuration problem that cause the error below. I know there are a tons of similar problem but I read a lot of answer that stackoverflow suggest with my title but I don't find the right answer yet.
Description:
Field collaborateurJpaRepository in com...infrastructure.persistence.user.UserRepositoryImpl required a bean of type 'com...infrastructure.persistence.jurisdiction.CollaborateurJpaRepository' that could not be found.
Action:
Consider defining a bean of type 'com...infrastructure.persistence.jurisdiction.CollaborateurJpaRepository' in your configuration.
Before to give some details of the code, I think it could be nice that I describe you brievly the context.
I work on a client project which has 8 maven modules (DDD methods) because at the end of the year 4 modules will be separate in an other server.
Recently we create a second oracle database so I had to create multiple configuration to refer to the good dataSource.
I think the problem is due to bad datasource configuration that block the bean spring instanciation.
We are using spring boot version 1.5.7.release.
First Infrastructure configuration
#Configuration
#ComponentScan(basePackages = "com...jade")
#EnableTransactionManagement
#EnableJpaRepositories(entityManagerFactoryRef = "jadeEntityManager", transactionManagerRef = "jadeTransactionManager")
#EntityScan(basePackages = { "com...jade", "org.springframework.data.jpa.convert.threeten" })
#Profile({"ARA_JADE_CONF", "LOCAL_JADE_CONF"})
public class InfrastructureConfig {
private final static int JDBC_FETCH_SIZE = 1000;
#Autowired
private Environment environment;
#Bean
public LocalContainerEntityManagerFactoryBean jadeEntityManager() throws SQLException {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSourceJade());
em.setPackagesToScan(new String[] {"com...jade"});
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
#Bean
#Primary
public OracleDataSource dataSourceJade() throws SQLException {
OracleDataSource dataSource = new OracleDataSource();
dataSource.setUser(environment.getProperty("db.datasource.jade.username"));
dataSource.setPassword(environment.getProperty("db.datasource.jade.password"));
dataSource.setURL(environment.getProperty("db.datasource.jade.url"));
dataSource.setImplicitCachingEnabled(true);
dataSource.setFastConnectionFailoverEnabled(true);
return dataSource;
}
#Bean(name="jdbcTemplateJade")
public JdbcTemplate jdbcTemplateJade() throws SQLException {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSourceJade());
jdbcTemplate.setResultsMapCaseInsensitive(true);
jdbcTemplate.setFetchSize(JDBC_FETCH_SIZE);
return jdbcTemplate;
}
#Bean
public PlatformTransactionManager transactionManager() throws SQLException{
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(jadeEntityManager().getObject());
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
} ...
Seconde Infrastructure configuration
#Configuration
#ComponentScan(basePackages = "com.bnpparibas.sit.risk.art")
#EnableTransactionManagement
#EnableJpaRepositories(entityManagerFactoryRef = "artEntityManager", transactionManagerRef = "artTransactionManager")
#EntityScan(basePackages = { "com...art", "org.springframework.data.jpa.convert.threeten" })
#Profile({"LOCAL_ART_CONF,'ARA_ART_CONF"})
public class ArtInfrastructureConfig {
private final static int JDBC_FETCH_SIZE = 1000;
#Autowired
private Environment environment;
#Bean
#Primary
public LocalContainerEntityManagerFactoryBean artEntityManager() throws SQLException {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSourceArt());
em.setPackagesToScan(new String[] {"com...art.infrastructure.persistence"});
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
#Bean
#Primary
public OracleDataSource dataSourceArt() throws SQLException {
OracleDataSource dataSource = new OracleDataSource();
dataSource.setUser(environment.getProperty("db.datasource.art.username"));
dataSource.setPassword(environment.getProperty("db.datasource.art.password"));
dataSource.setURL(environment.getProperty("db.datasource.art.url"));
dataSource.setImplicitCachingEnabled(true);
dataSource.setFastConnectionFailoverEnabled(true);
return dataSource;
}
#Bean
#Primary
public PlatformTransactionManager artTransactionManager()throws SQLException{
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(artEntityManager().getObject());
return transactionManager;
}
#Bean
#Primary
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}...
Interface link to Entity.
#DDD.Repository
#Repository
public interface CollaborateurJpaRepository extends CrudRepository<Collaborateur,String>{
#Query("FROM ART_PARAM.ART_USER u WHERE u.refogUID = :uid")
Collaborateur findCollaborateurById(#Param("uid") String uid);
}
Class that contain the autowired interface to retrieve some data of the second database.
#DDD.RepositoryImpl
#Repository
#Primary
public class UserRepositoryImpl implements UserRepository {
#Autowired
private CollaborateurJpaRepository collaborateurJpaRepository;
#Override
//#Cacheable(cacheNames = CacheConfig.CACHE_JURIDICTION, key = CacheConfig.CACHE_KEY_UTILISATEUR_ID)
#Transactional("entityManagerFactoryArt")
public User retrieveUser(UserId userId) {
if(userId.getValue() == null) {
return null;
} else {
Collaborateur collaborateur = collaborateurJpaRepository.findOne(userId.getValue());
return new User(collaborateur.getRefogUID(),collaborateur.getRefogFirstName(),collaborateur.getRefogLastName(),collaborateur.getProfile(),collaborateur.isActiveUser(),collaborateur.isBankingSecrecy());
}
}

Why is my entitymanager in Playframework 2.5 still null?

I want to use Playframework 2.5 together with Spring and JPA. I found the following template https://github.com/jamesward/play-java-spring where it works perfectly, unfortunately it’s not for Playframework 2.5. So I decided to adapt this template and create my own one for Playframework 2.5. However, my entitymanager in my controller Application is still null. What am I doing wrong? My code looks like the following:
AppConfig.java
package config;
#Configuration
#ComponentScan({"daos","services","controllers","models"})
public class AppConfig {
}
DataConfig.java
package config;
#Configuration
#EnableTransactionManagement
public class DataConfig
{
#Bean
public EntityManagerFactory entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setShowSql(true);
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setPackagesToScan("models");
entityManagerFactory.setJpaVendorAdapter(vendorAdapter);
entityManagerFactory.setDataSource(dataSource());
entityManagerFactory.setJpaPropertyMap(new HashMap<String, String>(){{
put("hibernate.hbm2ddl.auto", "create-drop");
put("hibernate.dialect","org.hibernate.dialect.PostgreSQLDialect");
}});
entityManagerFactory.afterPropertiesSet();
return entityManagerFactory.getObject();
}
#Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager(entityManagerFactory());
return transactionManager;
}
#Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
return dataSource;
}
}
Global.java
package config;
#Singleton
#Configuration
public class Global
{
private ConfigurableApplicationContext context;
#Inject
public Global(ApplicationLifecycle lifecyle)
{
this.context = new AnnotationConfigApplicationContext(AppConfig.class, DataConfig.class);
lifecyle.addStopHook(()-> {
context.close();
return CompletableFuture.completedFuture(null);
});
}
}
Application.java
package controllers;
#Controller
#Transactional
#Component
public class Application extends play.mvc.Controller
{
#PersistenceContext
private EntityManager em;
#Transactional
public Result index()
{
System.out.println("******************* EM " + this.em +" *************************");
return ok(index.render());
}
}
Thank you for your help!

How to set defaultHtmlEscape to true without XML in Spring MVC?

I want to avoid using XML configurations and therefore I made my AppConfig class where I have plenty of beans for different purposes.
I can't find how to prevent a XSS by setting defaultHtmlEscape inside my AppConfig. Everything I found was a config per form or globally in XML config.
My AppConfig now:
#EnableJpaRepositories(basePackages="org.maguss.repositories")
#EnableTransactionManagement
#EnableWebMvc
#Configuration
#ComponentScan({ "org.maguss.*" })
#Import({ SecurityConfig.class })
public class AppConfig {
#Bean(name = "dataSource")
public DriverManagerDataSource dataSource() {
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver");
driverManagerDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test");
driverManagerDataSource.setUsername("root");
driverManagerDataSource.setPassword("");
return driverManagerDataSource;
}
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/pages/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
//////////////////////////
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "org.maguss.model" });
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "update");
// properties.setProperty("hibernate.hbm2ddl.auto", "create");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
return properties;
}
//////////////////////////
}
Today I ran into the same question, and found two ways to achieve this.
1. Add an entry to the application.properties file
You can add the following entry to the application.properties file:
server.servlet.context-parameters.defaultHtmlEscape=true
2. Create a WebServerFactoryCustomizer bean
Alternatively, you can create a WebServerFactoryCustomizer bean to apply the customisation:
import java.util.Map;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.util.WebUtils;
#Component
public class WebServerCustomisations
implements WebServerFactoryCustomizer<AbstractServletWebServerFactory>
{
#Override
public void customize(AbstractServletWebServerFactory factory)
{
Map<String, String> initParams = factory.getInitParameters();
initParams.put(WebUtils.HTML_ESCAPE_CONTEXT_PARAM, Boolean.toString(true));
}
}
Note that this method will only be applied for those web servers that have a factory deriving from AbstractServletWebServerFactory. At the moment, it looks like this is Tomcat, Jetty and Undertow.
I guess you should have a AbstractAnnotationConfigDispatcherServletInitializer instead of traditional web.xml, based on that you can:
public class YourServletInititializer extends AbstractAnnotationConfigDispatcherServletInitializer {
// root config, web config and servlet mapping
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.setInitParameter("defaultHtmlEscape", "true")
super.onStartup(servletContext);
}
}

Better way to define a beans in class in spring

In an spring 4 application I creating two beans as below :
<!-- schemaFactory-->
<bean id="schemaFact" class="javax.xml.validation.SchemaFactory"
factory-method="newInstance">
<constructor-arg value="http://www.w3.org/2001/XMLSchema" />
</bean>
<!-- schema -->
<bean id="schema" class="javax.xml.validation.Schema"
factory-bean="schemaFact" factory-method="newSchema">
<constructor-arg value="classpath:/configs/sample.xsd" />
</bean>
One generates the schema factory and the other uses the factory (to validate xml against xsd).
And in the code:
public class example {
#Inject
private Schema aschema;
......
private validate(){
Validator validator = aschema.newValidator();
validator.validate(xmlFile);
}
}
This works fine, but I wonder if it is possible to write this spring.xml in a way that we don't need to define factory bean separately (and have a simpler spring.xml at the end). As you can see I only need schema bean to be injected in my example class and schemaFact in not needed at all.
Well injected dependencies have to spring beans whether you are using them directly or not.
So even if you are not using SchemaFactory directly in your code but to inject it as dependency in another spring bean, both have to be spring managed beans
You can consider using annotations then you don't need spring file at all.
This is some sample code to create bean in java class. Can create any bean here and autorwired in related class.
This annotations gave us big support to achive it ex- #Configuration
import java.util.Properties;
import javax.persistence.SharedCacheMode;
import........
#Configuration
#ComponentScan(basePackages = {"<package>"})
#EnableTransactionManagement
#PropertySources(value = {#PropertySource(value = {"<property file path>"})})
public class ModulesConfig {
private static final Logger log = LoggerFactory.getLogger(ModulesConfig.class);
#Autowired
private Environment environment;
#Bean(destroyMethod = "close")
public BoneCPDataSource getDataSource() {
BoneCPDataSource dataSource = new BoneCPDataSource();
dataSource.setDriverClass(environment.getProperty("database.driver"));
dataSource.setJdbcUrl(environment.getProperty("database.url"));
dataSource.setUsername(environment.getProperty("database.username"));
dataSource.setPassword(environment.getProperty("database.password"));
dataSource.setIdleConnectionTestPeriodInMinutes(30);
dataSource.setMaxConnectionsPerPartition(5);
dataSource.setMinConnectionsPerPartition(2);
dataSource.setPartitionCount(3);
dataSource.setAcquireIncrement(2);
dataSource.setStatementsCacheSize(100);
return dataSource;
}
#Bean
#Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
Properties jpaProperties = new Properties();
jpaProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
jpaProperties.setProperty("hibernate.showSql", "false");
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(getDataSource());
em.setPersistenceUnitName("entityManagerFactory");
em.setPackagesToScan("<packages>");
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(jpaProperties);
em.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE);
return em;
}
#Bean(name = "transactionManager1")
#Primary
public JpaTransactionManager getTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
#Bean(name = "transactionManager2")
public JpaTransactionManager getTransactionManager2() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory2().getObject());
return transactionManager;
}
#Bean
#Qualifier("VoucherServiceMarshaller")
public Jaxb2Marshaller getVoucherServiceMarshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath(environment.getProperty("voucher.service.marshaller.contextPath"));
return marshaller;
}
#Bean
#Qualifier("VoucherServiceTemplate")
public WebServiceTemplate getVoucherServiceTemplate() {
WebServiceTemplate template = new WebServiceTemplate(getVoucherServiceMarshaller());
template.setDefaultUri(environment.getProperty("voucher.service.defaultUri"));
return template;
}
#Bean
public VoucherServiceProxy getVoucherServiceProxy() {
VoucherServiceProxy voucherServiceProxy = new VoucherServiceProxy();
return voucherServiceProxy;
}
#Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
#Bean
public JavaMailSender javaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
Properties mailProperties = new Properties();
mailProperties.put("mail.smtp.host", environment.getProperty("mail.smtp.host"));
mailProperties.put("mail.smtp.socketFactory.port", environment.getProperty("mail.smtp.socketFactory.port"));
mailProperties.put("mail.smtp.socketFactory.class", environment.getProperty("mail.smtp.socketFactory.class"));
mailProperties.put("mail.smtp.auth", environment.getProperty("mail.smtp.auth"));
mailSender.setJavaMailProperties(mailProperties);
mailSender.setUsername(environment.getProperty("mail.username"));
mailSender.setPassword(environment.getProperty("mail.password"));
return mailSender;
}
#Bean
public ChargingGatewayServiceProxy getChargingGatewayServiceProxy() {
ChargingGatewayServiceProxy chargingGatewayServiceProxy = new ChargingGatewayServiceProxy();
return chargingGatewayServiceProxy;
}
#Bean
#Qualifier("ChargingGatewayServiceMarshaller")
public Jaxb2Marshaller getChargingGatewayServiceMarshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath(environment.getProperty("cg.service.marshaller.contextPath1"));
return marshaller;
}
#Bean
#Qualifier("ChargingGatewayServiceTemplate")
public WebServiceTemplate getChargingGatewayServiceTemplate() {
WebServiceTemplate template = new WebServiceTemplate(getChargingGatewayServiceMarshaller());
template.setDefaultUri(environment.getProperty("cg.service.url"));
template.setMessageSender(getMessageSender());
return template;
}
#Bean
public HttpComponentsMessageSender getMessageSender() {
HttpComponentsMessageSender httpComponentsMessageSender = new HttpComponentsMessageSender();
httpComponentsMessageSender.setConnectionTimeout(Integer.parseInt(environment.getProperty("cg.connection.timeout")));
httpComponentsMessageSender.setReadTimeout(Integer.parseInt(environment.getProperty("cg.read.timeout")));
return httpComponentsMessageSender;
}
#Bean
public RestTemplate restTemplate() {
return new RestTemplate(clientHttpRequestFactory());
}
private ClientHttpRequestFactory clientHttpRequestFactory() {
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setReadTimeout(50000);
factory.setConnectTimeout(50000);
return factory;
}
#Bean
public Cache cacheTemp() {
net.sf.ehcache.CacheManager cm = net.sf.ehcache.CacheManager.create().getInstance();
cm.addCache("cacheTemp");
Cache cache = cm.getCache("cacheTemp");
return cache;
}
#Bean
public Cache cacheActive() {
net.sf.ehcache.CacheManager cm = net.sf.ehcache.CacheManager.create().getInstance();
cm.addCache("cacheActive");
Cache cache = cm.getCache("cacheActive");
return cache;
}
#Bean
public Cache cache() {
net.sf.ehcache.CacheManager cm = net.sf.ehcache.CacheManager.create().getInstance();
cm.addCache("cache");
Cache cache = cm.getCache("cache");
return cache;
}
}

Spring #Transactional not working In standalone application

I have a standalone application in which I am trying to populate a database.
My application config looks like:
#Configuration
#EnableTransactionManagement
#PropertySource(value = { "classpath:classpath property file" })
#ComponentScan(basePackages = { my packages to scan })
public class PersistenceJPAConfig {
#Bean
public EntityManagerFactory entityManagerFactoryBean() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { packages to scan});
JpaVendorAdapter vendorAdapter = jpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
em.afterPropertiesSet();
return em.getObject();
}
#Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setDatabase(Database.ORACLE);
return jpaVendorAdapter;
}
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
dataSource.setUrl(url);
dataSource.setUsername(dbUser);
dataSource.setPassword(dbPassword);
return dataSource;
}
#Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactoryBean());
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
return new Properties() {
{ // Hibernate Specific:
setProperty("hibernate.hbm2ddl.auto", "validate");
setProperty("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
}
};
}
}
However when I am trying to persist something in database, the annotation is failing with error:
Exception in thread "main" javax.persistence.TransactionRequiredException: No transactional EntityManager available
In the resulting error stack, I don't see the transactional advice being applied.
The file that contains transactional annotation is something like this:
import org.springframework.transaction.annotation.Transactional;
#Service
public class MyService {
#Autowired
private MyDao myDao;
#Transactional
public void save(MyEntity e) {
myDao.save(e);
}
}
The MyDao class is something like this:
#Repository
public class MyDao {
#PersistenceContext
private EntityManager entityManager;
public void save(MyEntity e) {
entityManager.persist(e);
}
}
I am calling the function from my Main method as follows:
public static void main(String[] args) {
try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext()) {
ctx.scan(CONFIG_PACKAGE);
ctx.refresh();
myService = ctx.getBean(MyService.class);
Thread.sleep(10 * 1000);
myService.save(entity);
...
}
Stack trace looks something like this(edited to remove too specific traces pertaining to my code):
Exception in thread "main" javax.persistence.TransactionRequiredException: No transactional EntityManager available
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:275)
at com.sun.proxy.$Proxy27.persist(Unknown Source)
at mypackage.MyDao.save(MyDao.java:42)
at mypackage.MyDao$$FastClassBySpringCGLIB$$758201c8.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
at mypackage.MyDao$$EnhancerBySpringCGLIB$$9bd3b4fc.save(<generated>)
at mypackage.MyService.save(MyService.java:176)
at mypackage.MyService$$FastClassBySpringCGLIB$$5c0a03f6.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:649)
at mypackage.Run.main(Run.java:109)
Can anyone please help me with this, i.e. what I might be doing wrong?
Thanks for your help
You need to add #EnableJpaRepositories(basePackages = "base package") annotation in the configuration class.

Categories

Resources