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..
Related
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.
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..
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.
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.
I need to know if its possible in Spring to derive a value for a Property by combination of a System-Property and a Customized-Property defined over a PropertyFile.
What I've done:
1) Configured a -D argument in server as : -Dapp.Env="dev"
2) In my spring-config.xml, defined datasource details as below:
<!-- DataSource configurations -->
<bean id="myDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
init-method="init" destroy-method="close">
<property name="uniqueResourceName" value="myDataSource" />
<property name="xaDataSourceClassName" value="${my.database.xaDriver.class}" />
<property name="xaProperties">
<props>
<prop key="URL">#{systemProperties['appEnv']}.${my.database.jdbcUrl}</prop>
<prop key="user">#{systemProperties['appEnv']}.${my.database.user}</prop>
<prop key="password">#{systemProperties['appEnv']}.${my.database.password}</prop>
</props>
</property>
<property name="maxPoolSize" value="${my.database.maxPoolSize}" />
<property name="minPoolSize" value="${my.database.minPoolSize}" />
<property name="borrowConnectionTimeout" value="60" />
<property name="maintenanceInterval" value="120" />
</bean>
3) Defined the following properties in my .properties file:
my.database.xaDriver.class=oracle.jdbc.xa.client.OracleXADataSource
my.database.initialPoolSize=2
my.database.maxPoolSize=10
my.database.minPoolSize=2
dev.my.database.jdbcUrl=jdbc:oracle:thin:#test.com:1535:myDb
dev.my.database.user=myuserid
dev.my.database.password=mypwd
4) Defined .properties file location in the spring-config.xml as :
<context:property-placeholder location="/WEB-INF/spring/spring-config.properties" />
What I get on start of server :
Throwable occurred: org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'myDataSource' defined in ServletContext resource [/WEB-INF/spring/spring-config.xml]: Could not resolve placeholder 'my.database.jdbcUrl' in string value "#{systemProperties['appEnv']}.${my.database.jdbcUrl}"
What I also tried :
5) Defined a property in .properties file as below:
app.Env=dev
6) Modified the datasource bean configuration as below:
<prop key="URL">${app.Env}.${my.database.jdbcUrl}</prop>
<prop key="user">${app.Env}.${my.database.user}</prop>
<prop key="password">${app.Env}.${my.database.password}</prop>
However on start of server, I get same exception message :
Throwable occurred: org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'myDataSource' defined in ServletContext resource [/WEB-INF/spring/spring-config.xml]: Could not resolve placeholder 'my.database.jdbcUrl' in string value "${app.Env}.${my.database.jdbcUrl}"
Can someone help me out in pointing out what mistake I might be doing and what is/are the possible fix for this issue ?
1) You can read system properties into Spring bean:
<bean id="systemProperties" class="java.lang.System" factory-method="getProperties"/>
and then use multiple property resolvers
2) You can use flag systemPropertiesMode of PropertyPlaceholderConfigurer
3) You can write your custom bean factory that would produce single java.util.Properties object from system properties and file properties.
That bean would have method
public Properties merge() {
Properties merged = new Properties();
for (Properties p : properties) {
if (p != null) {
merged.putAll(p);
}
}
return merged;
}
Invoked in spring like that:
<bean id="factory" class="my.Factory">
<property name="properties">
<util:list>
<bean class="java.lang.System" factory-method="getProperties"/>
<bean ref="otherProperties">
</util:list>
</property>
</bean>