How to configure 'entityCacheStrategies' in spring4.3.x - caching

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.

Related

Spring Bean is not writable or has an invalid setter method

I'm experimenting with Spring, I'm following the book: Spring: A developer's notebook. I'm getting this error:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'validateFile' defined in class path resource [batch-config.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'customersDAO' of bean class [com.emp.ValidateCustomer]: Bean property 'customersDAO' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
Below is my batch-config.xml:-
<bean id="validateFile" class="com.emp.ValidateCustomer" >
<property name="customersDAO">
<bean class="com.emp.dao.CustomerDao">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</property>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="customerdb"/>
<property name="packagesToScan" value="com.emp" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">false</prop>
<prop key="hibernate.jdbc.batch_size">50</prop>
<prop key="hibernate.default_batch_fetch_size">50</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.use_sql_comments">false</prop>
<prop key="hibernate.generate_statistics">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">false</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
</props>
</property>
</bean>
</bean>
Below is CustomersDao.java:-
#Repository
public class CustomersDao {
#SuppressWarnings("deprecation")
private HibernateTemplate hibernateTemplate=null;
#Autowired
#Qualifier("sessionFactory")
public void setSessionFactory(SessionFactory sessionFactory) {
hibernateTemplate = new HibernateTemplate(sessionFactory);
}
}
And in ValidateCustomer.java:-
#Autowired
private CustomersDao customersDAO;
Please help.
As #MarcosBarbero says, without seeing more of ValidateCustomer.java, it's impossible to be definitive about the problem.
What annotations are on the ValidateCustomer class? I have no problem with Autowired for a private property when the enclosing class is a component or service. If it's not, then do you have a public setter? The property is not public, if the setter is not public, Spring won't be able to set it.

Bean property 'sessionFactoy' is not writable or has an invalid setter method

Working on spring+hibernate+maven code.
here's my StockDaoImpl class..
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.mkyong.stock.dao.StockDao;
import com.mkyong.stock.model.Stock;
public class StockDaoImpl extends HibernateDaoSupport implements StockDao{
public void save(Stock stock){
getHibernateTemplate().save(stock);
}
...
My sessionfactory defined in an xml..
<!-- Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibenate.dialect">org.hibernate.dialect.DerbyDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>/Hibernate/Stock.hbm.xml</value>
</list>
</property>
</bean>
I get the following error in console..Bean property 'sessionFactoy' is not writable or has an invalid setter method...
I tried writing a setter function for sessionfactory in StockDaoImpl...But I get an error saying 'setSessionFactory() in HibernateDaoSupport cannot be overridden'.
Can anyone pls tell me how to resolve the issue..

no writeable property 'url' in class 'oracle.jdbc.xa.client.OracleXADataSource'

I am writing a JTA transaction management module for the Spring application by Atomikos, everything assumed to be properly setup:
<bean id="dataSource_JDBC_01" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<property name="uniqueResourceName"><value>dataSource01</value></property>
<property name="xaDataSourceClassName"><value>${database_01.xadriver}</value></property>
<property name="xaProperties">
<props>
<prop key="databaseName">${database_01.username}</prop>
<prop key="user">${database_01.username}</prop>
<prop key="password">${database_01.password}</prop>
<prop key="url">${database_01.url}</prop>
</props>
</property>
<property name="poolSize"><value>1</value></property>
</bean>
<jee:jndi-lookup id="dataSource_01" jndi-name="jdbc/DataSource01" default-ref="dataSource_JDBC_01" />
Values to those placeholders are quoted from here:
database_01.xadriver=oracle.jdbc.xa.client.OracleXADataSource
database_01.url=jdbc\:oracle\:thin\:#localhost\:1521\:orcl
database_01.username=USER_01
database_01.password=PASS_01
But Atomikos throw an exception:
no writeable property 'url' in class 'oracle.jdbc.xa.client.OracleXADataSource'
2014-12-11 12:00:23,098 -- WARN -- com.atomikos.jdbc.AtomikosSQLException -- Cannot initialize AtomikosDataSourceBean
com.atomikos.beans.PropertyException: no writeable property 'url' in class
'oracle.jdbc.xa.client.OracleXADataSource'
at com.atomikos.beans.PropertyUtils.getSetter(PropertyUtils.java:286)
at com.atomikos.beans.PropertyUtils.setDirectProperty(PropertyUtils.java:200)
at com.atomikos.beans.PropertyUtils.setProperty(PropertyUtils.java:110)
at com.atomikos.beans.PropertyUtils.setProperties(PropertyUtils.java:186)
Followed by:
javax.naming.NamingException: Another resource already exists with name dataSource01 - pick a different name
I really cannot tell what is wrong here.
Turns out it just a matter of capitalize the name of property URL. From Oracle API document class OracleXADataSource has a setter method as setURL(), so that the bean name should use
<prop key="URL">${database_01.url}</prop>
instead of
<prop key="url">${database_01.url}</prop>
Cheers..

Cannot get spring bean?

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.

Spring Velocity Exception while loading applicatonContext

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?

Resources