getTopLinkTemplate is null with Spring - java

I'm trying to use TopLink with Spring but I'm having a problem. I'm using it in a webservice (CXF).
When I use getTopLinkTemplate(), the resul is null.
Here is my applicationContext.xml :
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#*************" />
<property name="username" value="*****" />
<property name="password" value="*****" />
</bean>
<bean id="mySessionFactory"
class="org.springframework.orm.toplink.LocalSessionFactoryBean">
<property name="configLocation" value="toplink-sessions.xml" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="myProductDao" class="ToplinkExecPS.ExecPS">
<property name="sessionFactory">
<ref local="mySessionFactory" />
</property>
</bean>
My code is :
public class ExecPS extends TopLinkDaoSupport{
public Vector Exec(String test)
{
TopLinkTemplate t;
t = getTopLinkTemplate();
if (t == null)
System.out.println("template is null");
}
}
So, when I execute this code, I have "template is null" in the console and a nullPointerException when I try to use the variable "t".
For information, the connection to the database with TopLink is successful.
[TopLink - Infos] : 2012.05.23 03:45:22.113--ServerSession(4812898)--Thread(Thread[main,5,main])--Session - connexion réussie
I have testing so many things and I'm still stuck. I hope you will help me.
[EDIT]
OK I'm really a noob. I just forget to get my bean before call the method...
If anyone get on this thread, there is the code:
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext(new String[]{"ToplinkContext.xml"} );
ExecPS exec = (ExecPS)context.getBean("myProductDao");

Not 100% on this one but I would be suspicious of this line:
<property name="configLocation" value="toplink-sessions.xml" />
Unsure toplink-sessions.xml is on your classpath and try the following:
<property name="configLocation" value="classpath:toplink-sessions.xml" />

Related

java.lang.IllegalAccessError: org.apache.commons.dbcp.DelegatingPreparedStatement.isClosed()Z

i tried to make integration of spring and mybatis.
jdk:1.8
run my test:
#Test
public void testFindUserById() throws Exception{
UserMapper userMapper=(UserMapper)applicationContext.getBean("userMapper");
User user=userMapper.findUserById(1);
System.out.println(user);
}
and error:the full stacktrace
java.lang.IllegalAccessError: org.apache.commons.dbcp.DelegatingPreparedStatement.isClosed()Z
The spring configuration file:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/custom?useSSL=false" />
<property name="username" value="root" />
<property name="password" value="qqwe5631652" />
<property name="maxIdle" value="5" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:SqlMapConfig.xml" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<bean id="userDao" class="dao.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
</beans>
file's structure
all of ‘.jar’
It 's java.lang.IllegalAccessError about authority?
i have no idea
i change commons-dbcp-1.2.1.jar into commons-dbcp-1.4.jar ,and it 's ok now!
Yeah, your solution was right.
If you take a look to DelegatingPreparedStatement.isClosed() javadoc you can see that this method is protected so any attempt from your side to invoke this method will end up in an IllegalAccessException because you don't have permissions to do this. Newer versions of this library has turned this metod up public

Spring #Transactional - Rollback is not happening

I am new to spring and working on a sample program using Spring jdbc. this is to check how spring #Trsactional working and rolling back the changes to the Db if there is an exception.
But I am not able to achieve this. Through I am raising an exception in one of the DB update, still it's inserting the data to DB and not rolling back for that batch. For ex. after inserting 5000 I am raising an exception, so ideally it should rollback all the changes(for the current batch) to all the tables and total rows in Db should be 4000.
I know somewhere I am making mistake but not able to figure it out. Not sure if this is a correct approach.
I tried all possible ways available in the Internet, but still no luck. please help me to resolve this issue.
Here is my sample application https://github.com/rajarshp/JavaSample
Code Snippet
#Transactional(rollbackFor={Exception.class})
public void executeDB(int count) throws Exception
{
CreateAccount newacc = new CreateAccount(jdbcTemplate);
CreateUser newusr = new CreateUser(jdbcTemplate);
//BalanceUpdate newbal = new BalanceUpdate(jdbcTemplate);
newacc.addList(acclist);
newusr.addToList(usrlist);
//newbal.addList(ballist);
newusr.execute(); // insert data to db
newacc.addAccount(); // insert data to db
//newbal.addBalance(); // insert data to db
newacc.getAccList().clear();
newusr.getUserList().clear();
//newbal.getBalanceList().clear();
if(count == 5000)
{
Thread.sleep(1000);
throw new Exception("Rollback");
}
count += 1000;
//throw new Exception();
}
XML:
<context:component-scan base-package="com.example"></context:component-scan>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe" />
<property name="username" value="system" />
<property name="password" value="root" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="startit" class="com.example.springtransaction.GlobalClass">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="dbupdate" class="com.example.springtransaction.DbUpdate">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
Create bean for all Db operation classes like createUser or Cretae account in the xml file. remove the initialization on these classes from db operation class and use setter method to inject it from the xml. Post that call your db operation method. It should work.
<bean id="newaccount" class="com.example.springtransaction.CreateAccount">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="newuser" class="com.example.springtransaction.CreateUser">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="dbupdate" class="com.example.springtransaction.DbUpdate">
<property name="newaccount" ref="newacc"></property>
<property name="newuser" ref="newusr"></property>
</bean>

Should I Split Spring context file

I am trying to learn the Spring framework. I am making a simple test application. I have a Client that calls Service that calls a DAO.
The Client calls the Service like this:
XML
<bean id="myService" class="test.package.service.MyServiceImpl">
<property name="indexFilePath" value="${indexFilePath}" />
<property name="pdfFilePath" value="${pdfFilePath}" />
</bean>
Java
public static void main(String[] args)
{
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyService myService = (MyService)context.getBean("myService");
myService.doStuff();
context.close();
}
I want the Service to call the DAO:
XML
<bean id="trackingDAO" class="test.package.dataaccess.TrackingDAOImpl">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${trackingDb.driver}" />
<property name="url" value="${trackingDb.url}" />
<property name="username" value="${trackingDb.username}" />
<property name="password" value="${trackingDb.password}" />
</bean>
My problem is that I have both of these XML pieces in the same file. So I do not know how to access the DAO bean. I do not believe I can open the same context when it is still open in "main". Should I create a second context file? If so, what is a food rule of thumb for when I should create a new context file? I do not like the idea of have many of these. Or perhaps the DAO should be a property of the Service?
<bean id="myService" class="test.package.service.MyServiceImpl">
<property name="indexFilePath" value="${indexFilePath}" />
<property name="pdfFilePath" value="${pdfFilePath}" />
<property name="dao" ref="trackingDAO" />
</bean>
Within your service, add a property of dao, like you mentioned.
public class MyServiceImpl {
....
TrackingDAO dao; //assuming thats the interface , or use Impl.
....
}
Year! U are right "the DAO should be a property of the Service"!
and the piece just need one in U Spring contxt xml file!
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${trackingDb.driver}" />
<property name="url" value="${trackingDb.url}" />
<property name="username" value="${trackingDb.username}" />
<property name="password" value="${trackingDb.password}" />
</bean>
this piece just need one in U Spring contxt xml file!
Try ! it's will work well!

how can i get database password at runtime before connecting to the database

in my applicationcontext.xml i have this :
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/dashboardsupervisor" />
<property name="username" value="root" />
<property name="password" value="1234" />
</bean>
here i am connecting with my database :
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
MySQLRdbHelper rdbHelper = (MySQLRdbHelper)
ctx.getBean("ManagerSupervisor");
What is want is to NOT read the password "1234" from my applicationcontext.xml
and read it from some properties file in my local drive .
as this will be running on different machines and every one have different passwords.
Can i achieve this .
thanks
Yes, you can, and the key to this is Springs PropertyPlaceholderConfigurer.
For example, you create a file on your file system called database.properties, containing your password (note, that you can also add more settings to this file, like username, JDBC url, etc).
jdbc.password=1234
Next, you need to declare a PropertyPlaceholderConfigurer bean and point it to the database.properties file:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>path/to/database.properties</value>
</property>
</bean>
Note that the path is interpreted as a classpath resource, unless it is prefixed with file:.
Finally, replace the configuration of your dataSource bean: replace
<property name="password" value="1234" />
with
<property name="password" value="${jdbc.password}" />
You could use profiles:
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.getEnvironment().setActiveProfiles("dev1");
ctx.load("*Context.xml");
ctx.refresh();
<bean id="database1" profile="dev1"/>
<bean id="database2" profile="dev2">
The best way is to create the data source in application server and configure as below in application.xml
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>YourDSName</value></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
.....
</bean>

Configuring apache dbcp PoolingDataSource with Spring

Tried to follow the pattern on apache dbcp examples, I understand everything except how and where the database properties come from and in which bean they have to be placed in application context.
I used Spring Data Source instead, but as I recall I configured it in hurry and I remember having difficulties with configuring the original dataSource provided by apache dbcp itself. So I happen to have time to face the problem and fulfill the original intent of using PoolingDataSource.
The reason I used Spring implementation is because it provides means of setting up the parameters to connect to database.
http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/jdbc/datasource/DriverManagerDataSource.html
According to http://commons.apache.org/dbcp/apidocs/org/apache/commons/dbcp/PoolingDataSource.html
There are no methods to populate configuration like url or load driver.
I tried to track it through the object pools etc. , but got really lost.
Replying upfront: Yes, I don't want to use apache basicDataSource.
So now I am returning to the problem and can't really understand where to fetch the parameters? Driver? Url? It seems that url, pw and username are set on connection factory. But where to fetch postgresql driver to be loaded?
Please help to complete the configuration.
(using spring for configuration)
<!-- the one I want to use now -->
<bean id="dataSource" class="org.apache.commons.dbcp.PoolingDataSource">
<constructor-arg><ref bean="pool"/></constructor-arg>
</bean>
<!-- the one I used before as a workaround
<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql:postgres"/>
<property name="username" value="magicUserName"/>
<property name="password" value="magicPassword"/>
</bean> -->
<bean id="pool" class="org.apache.commons.pool.impl.GenericObjectPool">
<property name="minEvictableIdleTimeMillis"><value>300000</value </property>
<property name="timeBetweenEvictionRunsMillis"><value>60000</value </property>
</bean>
<bean id="dsConnectionFactory" class="org.apache.commons.dbcp.DataSourceConnectionFactory">
<constructor-arg><ref bean="dataSource"/></constructor-arg>
</bean>
<bean id="poolableConnectionFactory" class="org.apache.commons.dbcp.PoolableConnectionFactory">
<constructor-arg index="0"><ref bean="dsConnectionFactory"/ </constructor-arg>
<constructor-arg index="1"><ref bean="pool"/></constructor-arg>
<constructor-arg index="2"><null/></constructor-arg>
<constructor-arg index="3"><null/></constructor-arg>
<constructor-arg index="4"><value>false</value></constructor-arg>
<constructor-arg index="5"><value>true</value></constructor-arg>
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
</beans>
I believe we are interested just in the first two, but I included everything just in case.
Seems to be there are many people using workarounds:
http://forum.springsource.org/showthread.php?10772-How-do-I-create-a-org-apache-commons-dbcp-PoolableConnection
You can config as below:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="<put database connection url here>" />
<property name="username" value="XXXXXX" />
<property name="password" value="XXXXXXXX" />
<property name="driverClassName" value="<database driver here>" />
</bean>
<bean id="pool" class="org.apache.commons.pool.impl.GenericObjectPool">
<property name="minEvictableIdleTimeMillis"><value>300000</value></property>
<property name="timeBetweenEvictionRunsMillis"><value>60000</value></property>
</bean>
<bean id="dsConnectionFactory" class="org.apache.commons.dbcp.DataSourceConnectionFactory">
<constructor-arg><ref bean="dataSource"/></constructor-arg>
</bean>
<bean id="poolableConnectionFactory" class="org.apache.commons.dbcp.PoolableConnectionFactory">
<constructor-arg index="0"><ref bean="dsConnectionFactory"/></constructor-arg>
<constructor-arg index="1"><ref bean="pool"/></constructor-arg>
<constructor-arg index="2"><null/></constructor-arg>
<constructor-arg index="3"><null/></constructor-arg>
<constructor-arg index="4"><value>false</value></constructor-arg>
<constructor-arg index="5"><value>true</value></constructor-arg>
</bean>
<bean id="pooledDS" class="org.apache.commons.dbcp.PoolingDataSource"
depends-on="poolableConnectionFactory">
<constructor-arg><ref bean="pool"/></constructor-arg>
</bean>
And you can use "pooledDS" (PoolingDataSource) the same any orther DataSource.
Ortherwise, i think you should simply use BacsicDataSource, you still can config number of connections in pool by "initialSize" and "maxActive":
<bean id="basicDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="removeAbandoned" value="true"/>
<property name="initialSize" value="10" />
<property name="maxActive" value="50" />
</bean>

Categories

Resources