Can't get bean from spring container in listener or filter classes.
Have you used something like this :
#Autowired
private ApplicationContext context;
ICustomer customer = (ICustomer) context.getBean("name"); // here name is the name of the bean you want to get context
look I have used this in my project like this ans works well :
String processorName = Introspector.decapitalize(command.getClass().getSimpleName() + "Processor");
ICommandProcessor processor = (ICommandProcessor) context.getBean(processorName);
here if I ll pass command Add then it ll pass processorName = AddProcessor and get it's context.
what is your requirement ? can you post code ?
Look this xml file then check yours from it :
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="packagesToScan" value="com.domain"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
</bean>
<!-- Transaction Manager -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
here : <property name="packagesToScan" value="com.domain"/> is important when you want to use #Autowired in my project it's com.domain, so refer this and make changes as you need. then again post.
Related
I want to change a property of a bean. I want to change it only once for performance (better when reading from XML), not in every bean instance instantiation. What is the best way to do it in Spring?
For elaborating and giving a concrete example:
Below is the datasource bean declaration in databaseContext.xml.
I want to decrypt ${jdbc.password} whose value is ENC(....) with JASYPT.
I could not do it with Jaspt Spring integration since Jaspt not compliant yet with Spring5 and not with Jasypt Hibernate integration since using a different datasource other than Hibernate.
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="springHikariCP" />
<property name="connectionTestQuery" value="SELECT 1 from dual" />
<property name="dataSourceClassName" value="oracle.jdbc.pool.OracleDataSource" />
<property name="maximumPoolSize" value="10" />
<property name="idleTimeout" value="30000" />
<property name="dataSourceProperties">
<props>
<prop key="url">${jdbc.url}</prop>
<prop key="user">${jdbc.user}</prop>
<prop key="password">${jdbc.password}</prop>
</props>
</property>
</bean>
This helped me a lot:
Spring property placeholder decrypt resolved property
Just want to add some small correction and extra notes about some findings:
In the link above it is written "location", but it must be "locations" as written below, where it resides at applicationContext.xml
<bean class="com.dummy.util.EncryptationAwarePropertySourcesPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:database.properties</value>
<value>classpath*:hibernate.properties</value>
</list>
</property>
</bean>
"PropertyPlaceholderConfigurer" is deprecated. But it still works. If you try to use the newly proposed class "PropertySourcesPlaceholderConfigurer", it has a bug that it does not call "convertPropertyValue" method as noted here: https://github.com/spring-projects/spring-framework/issues/13568. A workaround noted by the way there.
public class EncryptationAwarePropertySourcesPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
#Override
protected String convertPropertyValue(String originalValue) {
if (originalValue != null && originalValue.startsWith("ENC(")) {
return decrypt(originalValue);
}
return originalValue;
}
.
.
}
I encouter an issue "Spring transaction fail rollback". I have a service class which call 2 DAO to insert data into DB table.
emTrcvLineDAO.create(lineVo) fail to insert into table as the lineVo missing some mandatory fields, but emTrcvHeaderDAO.create(vo) fail rollback and the data still inserted in to DB successfully. I am wondering why it does not rollback as the two DAO are in the same transaction.
Any guys have idea on this? Thanks in advance.
public void saveEmTrcvHeader(List<EmTrcvHeaderVOImpl> voList, List<ResponseItem> responseItemList) {
for (EmTrcvHeaderVOImpl vo : voList) {
emTrcvHeaderDAO.create(vo);
List<EmTrcvLineVOImpl> lineList = vo.getLineList();
for (int i = 0; i < lineList.size(); i++) {
EmTrcvLineVOImpl lineVo = lineList.get(i);
lineVo.setEmTrcvHeaderId(vo.getEmTrcvHeaderId());
lineVo.setProjId(null);
emTrcvLineDAO.create(lineVo);
}
}
}
My transaction configuration:
<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="proxyTargetClass">
<value>true</value>
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED,-java.lang.Exception,-org.springframework.dao.DataAccessException</prop>
<prop key="*">PROPAGATION_REQUIRED,-java.lang.Exception,-org.springframework.dao.DataAccessException</prop>
</props>
</property>
</bean>
My service and dao defined as below:
<bean name="emTrcvHeaderService" parent="txProxyTemplate">
<property name="target">
<bean class="com.emtrcv.service.EmTrcvHeaderService">
<property name="emTrcvHeaderDAO">
<ref bean="emTrcvHeaderDAO"/>
</property>
<property name="emTrcvPubSelectIdsDAO">
<ref bean="emTrcvPubSelectIdsDAO"/>
</property>
<property name="emTrcvLineDAO">
<ref bean="emTrcvLineDAO"/>
</property>
</bean>
</property>
</bean>
<bean name="emTrcvHeaderDAO" class="com.emtrcv.dao.EmTrcvHeaderDAOImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean name="emTrcvPubSelectIdsDAO" class="com.emtrcv.dao.EmTrcvPubSelectIdsDAOImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean name="emTrcvLineDAO" class="com.emtrcv.dao.EmTrcvLineDAOImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
I think you have to mention when rollback should take place.
As per doc,
The concept of rollback rules is important: they enable you to specify which exceptions (and throwables) should cause automatic rollback. You specify this declaratively, in configuration, not in Java code. So, although you can still call setRollbackOnly() on the TransactionStatus object to roll back the current transaction back, most often you can specify a rule that MyApplicationException must always result in rollback.
Please refer http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html for more details
Finally I found the root cause. there are two duplicate Spring configuration files both define transaction management rules in the project, it make spring tranasction management not work. After removed one of them, it works.
I am migrating from spring3.x to spring4.3.x. I am using org.springframework.orm.hibernate5.LocalSessionFactoryBean in bean creation as follows
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="annotatedClasses">
<list>
<value>com.example.person.domain.Person</value>
</list>
</property>
<property name="mappingLocations">
<list>
<value>classpath*:com/example/person/domain/Person.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">${cache.providerClass}</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.memcached.dogpilePrevention">true</prop>
<prop key="hibernate.memcached.servers">${cache.memcached.servers}</prop>
<prop key="hibernate.memcached.keyStrategy">com.example.memcached.ExampleCacheStringKeyStrategy</prop>
<prop key="hibernate.memcached.deviceAttributeDao.keyStrategy">com.googlecode.hibernate.memcached.HashCodeKeyStrategy</prop>
<prop key="hibernate.memcached.EncodingDao.keyStrategy">com.googlecode.hibernate.memcached.HashCodeKeyStrategy</prop>
</props>
</property>
<property name="entityCacheStrategies">
<props>
<prop key="com.example.person.domain.TestAttribute">read-write,_domain</prop>
</props>
</property>
<property name="dataSource" ref="dataSource"/>
</bean>
I am getting following error
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'entityCacheStrategies' of bean class [org.springframework.orm.hibernate5.LocalSessionFactoryBean]: Bean property 'entityCacheStrategies' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.createNotWritablePropertyException(BeanWrapperImpl.java:242)
at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:423)
at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:280)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:95)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:75)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1514)
... 66 more
I am using spring-4.3.0.RELEASE. The LocalSessionFactoryBean doesn't have setter for entityCacheStrategies. Any idea how to support this in spring4.3.x?
The usage of entityCacheStrategies/setEntityCacheStrategies() has been deprecated in hibernate 5. A probable alternative from org.hibernate.cfg.Configuration : setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy)is also no longer in use.
But if you're open to configuring the cache using hibernate annotations library, then try this approach which makes the use of CacheConcurrencyStrategyenumerator.
You can apply appropriate Concurrency strategy at Entity level.
#Entity
#Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Clazz{..}
Please find more usages of CacheConcurrencyStrategy in the dev guide.
Scenario: In the application I have language-dependent property files which are used as templates to generate emails:
email-subscription_en.properties:
email.subject=You are successfully subscribed to list {0}
email.body=...
email-cancellation_en.properties:
email.subject=You are successfully unsubscribed from list {0}
email.body=...
and so on. Now in Spring context I would like to have these bundles:
<bean id="subscriptionMailProperties" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="org.company.email-subscription" />
</bean>
<bean id="cancellationMailProperties" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="org.company.email-cancellation" />
</bean>
be merged with these common language-independent properties which I would like to be declared in context:
<util:properties id="commonMailProperties">
<prop key="email.from">noreply#company.org</prop>
<prop key="email.to">{0}#company.org</prop>
</util:properties>
How is it possible?
As far as I know there is no support for this. You are trying to mix configuration with resource bundles. I feel what you currently have is right. If you do not have luxury of keeping it as it is, here is a way(more of a hack)
Implement org.springframework.context.MessageSource with 'commonMailProperties'(java.util.Properties) as dependency and say the bean id as 'commonMessageSource'.
In 'getMessage' implementations get the value from 'commonMailProperties'.
Inject 'commonMessageSource' to 'subscriptionMailProperties' and 'cancellationMailProperties', for 'parentMessageSource' property.
If somebody got interested in complete solution:
Create class PropertiesMessageSource:
/**
* {#link org.springframework.context.MessageSource} implementation that resolves messages via underlying
* {#link Properties}.
*/
public class PropertiesMessageSource extends AbstractMessageSource {
private Properties properties;
/**
* Set properties to use.
*/
public void setProperties(Properties properties) {
this.properties = properties;
}
#Override
protected MessageFormat resolveCode(String code, Locale locale) {
String property = properties.getProperty(code);
if (property == null) {
return null;
}
return createMessageFormat(property, locale);
}
}
Use it:
<bean id="commonMailProperties" class="org.company.PropertiesMessageSource">
<property name="properties">
<props>
<prop key="email.from">noreply#company.org</prop>
<prop key="email.to">{0}#company.org</prop>
</props>
</property>
</bean>
<bean id="subscriptionMailProperties" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="org.company.email-subscription" />
<property name="parentMessageSource">
<ref bean="commonMailProperties"/>
</property>
</bean>
ResourceBundleMessageSource (more exactly: all descendants of AbstractMessageSource) now has commonMessages property which can hold locale-independent values. For example while you want to have mail subject and body locale-dependant, some properties (mail from and mail to) are common across all bundles (check SPR-10291):
<bean id="mailProperties" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="org.mycompany.email" />
<property name="commonMessages">
<props>
<prop key="email.from">empty#mydomain.org</prop>
<prop key="email.to">%s#mydomain.org</prop>
</props>
</property>
</bean>
We use spring, velocity for email piece of code in our application and i got below exception. Any idea to solve this.
"org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'org.springframework.ui.velocity.VelocityEngineFactoryBean' to required type
'org.apache.velocity.app.VelocityEngine' for property 'velocityEngine'; nested exception is java.lang.IllegalStateException: Cannot convert value of type
[org.springframework.ui.velocity.VelocityEngineFactoryBean] to required type [org.apache.velocity.app.VelocityEngine] for property 'velocityEngine': no matching editors or conversion strategy found "
Following is my context configuration.
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="xxxx.US"/>
<property name="port" value="25"/>
<property name="javaMailProperties">
<props>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.smtp.auth">false</prop>
<prop key="mail.smtp.starttls.enable">false</prop>
<prop key="mail.debug">true</prop>
</props>
</property>
</bean>
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="velocityProperties">
<value>
resource.loader=class
class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
</value>
</property>
</bean>
<bean id="emailUtil" class="com.example.MailUtil">
<property name="mailSender" ref="mailSender" />
<property name="velocityEngine" ref="velocityEngine" />
</bean>
You do not need to reference the velocityEngine in your emailUtil bean. Everything else about your spring config is correct.
I grabbed the following code from my app to show you how we are able to use velocity templates.
private String generateMessageFromTemplate(User user, VelocityTemplateEnum velocityTemplateEnum) {
VelocityContext context = new VelocityContext();
context.put("user", user);
StringWriter stringWriter = new StringWriter();
String template = velocityTemplateDao.findById(velocityTemplateEnum.name()).getTemplate();
Velocity.evaluate(context, stringWriter, velocityTemplateEnum.name(), template);
return stringWriter.getBuffer().toString();
}
I have a similar setup only I autowire in the VelocityEngine and that's working for me. Is autowiring an option for you? Also, can you add the code for your MailUtil class? Maybe something isn't 100% right with the velocityEngine field/setter?