Spring Help

1 view
Skip to first unread message

Josh S

unread,
Aug 15, 2008, 3:25:33 PM8/15/08
to KCJava
I am working on a large scale J2EE project that I need some Spring
help on.

We are currently using EJB's (Stateless Session) for the transaction
management component (CMT), and I am wanting to convert that to Spring
Transaction management, probably still JTA.

The hope is that then I can leverage Spring to allow me to run tests
outside of the container if needed.


My problem seems to be configuring Spring correctly to control the
transactions. In some simple testing I am seeing transactions commit
when they shouldn't, and not commit when they should. Not sure if my
problem is related to my bean config for my business service,
transaction manager, data source, etc....

I will happily post out any code anyone wants to see, but I am really
needing a good example of how to do Spring Managed transactions with
raw JDBC.

Any help is appreciated.

new...@att.net

unread,
Aug 15, 2008, 4:03:44 PM8/15/08
to KCJ...@googlegroups.com
Have you looked at Spring's petstore example app?

One thing that happened to us is we tried to convert some apps in piecemeal fashion, and we got similar results to yours. The original approach was to use IbatisDAO with programmatic transactions. Trying to convert over a little at a time resulted in a situation where we had two database connection pools, the IbatisSimpleDataSource and DBCP, with different parts of the code grabbing the database connection from a different pool, with results like what you describe.

Newton



 
-------------- Original message from Josh S <jesm...@sbcglobal.net>: --------------
> --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups
> "KCJava" group.
> To post to this group, send email to KCJ...@googlegroups.com
> To unsubscribe from this group, send email to
> KCJava+un...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/KCJava?hl=en
> -~----------~----~----~----~------~----~------~--~---
>

Jason Bedell

unread,
Aug 15, 2008, 4:21:08 PM8/15/08
to KCJ...@googlegroups.com
Attached is a spring container config we have in production for a fairly small site. This uses a transaction proxy as a transaction management aspect on a service tier. The transaction proxy is being injected with a Hibernate transaction manager but it could be a JTA manager if you wanted.

I you want to share your Spring container config, I'm sure the group (I) would be happy to look at it. Hope this helps.

Jason Bedell
http://www.jasonbedell.com

http://blog.jasonbedell.com
http://www.linkedin.com/in/jasonbedell
http://twitter.com/jasonbedell
http://del.icio.us/jasonbedell
http://digg.com/users/jasonbedell
applicationContext.xml

Josh S

unread,
Aug 15, 2008, 4:40:03 PM8/15/08
to KCJava
I haven't looked that yet, in part because I am struggling to find it.
My office won't let us download things (even zip files) from the
internet. So I am stuck using what they have already pulled down. That
doesn't seem to include any example apps.

On Aug 15, 3:03 pm, newt...@att.net wrote:
>  Have you looked at Spring's petstore example app?
>
> One thing that happened to us is we tried to convert some apps in piecemeal fashion, and we got similar results to yours. The original approach was to use IbatisDAO with programmatic transactions. Trying to convert over a little at a time resulted in a situation where we had two database connection pools, the IbatisSimpleDataSource and DBCP, with different parts of the code grabbing the database connection from a different pool, with results like what you describe.
>
> Newton
>
>   -------------- Original message from Josh S <jesmit...@sbcglobal.net>: --------------

Josh S

unread,
Aug 15, 2008, 4:55:01 PM8/15/08
to KCJava
Beings I seem to be temporarially unable to upload a file (brain is a
little fried), I have included it below.

I am not sure by any means that I have it correct. I looked at the
example you provided, but what I am really hoping to get done is to
use the annotations. @Transactional, and let the proxied service beans
contain the information so that I don't have to manage a xml file.

My overall intent is to use a small test app (which I can bundle if
needed) to get an good understanding of how the Tx's work and then
replace the EJB layer in my main app with Spring. I am still at a
point where I can replace them all (we are almost to testing) so I
don't have to manage two different connection pools, etc, while doing
a piece-meal conversion.

But that's not an option when the Tx management doesn't work.


My app that I am testing with looks like this.

I have struts and a single action. It does nothing other than call
into a business service class to update a dummy record in the DB.

Home Action

WebApplicationContext context =
WebApplicationContextUtils.getWebApplicationContext(super.servlet.getServletContext());
FooServiceImpl foo = (FooServiceImpl)context.getBean("fooService");

System.out.println("The FooService class is : " +
foo.getClass().getCanonicalName());
foo.insertId(id);
System.out.println("Tried to insert id " + id);
id++;
int foundId = foo.getId();


System.out.println("The update completed successfully");
System.out.println("The returned id was : " + foundId);


FooService - Creates DAO, calls update method, returns ID found.


@Transactional
public class FooServiceImpl {

private static FooServiceImpl service = null;

public static FooServiceImpl getInstance(){
if (service == null){
service = new FooServiceImpl();
}
return service;
}

private FooServiceImpl(){

}

@Transactional(propagation=Propagation.REQUIRED)
public int insertId(int ID) {
TestDAO dao = new TestDAO();
dao.insertId(ID);
return dao.getId();
}

@Transactional(propagation=Propagation.SUPPORTS)
public int getId(){
TestDAO dao = new TestDAO();
return dao.getId();
}
}


TestDAO - Exeucte the SQL. Gets it's DataSource from the StaticConn
Manager class which looks up the DS using SpringBean call.


public class TestDAO {

public void insertId(int id){

String SQL = "insert into test (id, action_date) values (?,
current_timestamp);";
Connection conn = null;
try {
conn = ConnManager.getConnection("springDataSource");
PreparedStatement ps = conn.prepareStatement(SQL);
ps.setInt(1, id);
ps.execute();
} catch (SQLException e){
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e){

}
}
}

public int getId(){

String SQL = "select * from test order by action_date desc";
Connection conn = null;
int id = 0;
try {
conn = ConnManager.getConnection("springDataSource");
PreparedStatement ps = conn.prepareStatement(SQL);
ResultSet rs = ps.executeQuery();
if (rs.next()){
id = rs.getInt("id");
}
} catch (SQLException e){
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e){

}
}
return id;
}


ConnManager - Looks up DS from Spring config.

public class ConnManager {

private static Hashtable<String, DataSource> dsTable = new
Hashtable<String, DataSource>();

static Connection getConnection(String name){
Connection conn = null;
DataSource ds = null;
name = "springDataSource";
try {
if (dsTable.containsKey(name)){
conn = DataSourceUtils.doGetConnection(dsTable.get(name));
} else {
ClassPathXmlApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
ds = (DataSource)context.getBean(name);
conn = DataSourceUtils.doGetConnection(ds);
}
//conn.setAutoCommit(false);

System.out.println("The connection is transactional " +
DataSourceUtils.isConnectionTransactional(conn, ds));

} catch (SQLException e){
e.printStackTrace();
}

return conn;
}

}

applicationContext.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.0.xsd
">

<tx:annotation-driven transaction-manager="txManager" proxy-target-
class="true" />

<bean id="springDataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"
value="java:jdbc/SpringDB" />
<property name="lookupOnStartup" value="true" />
<property name="cache" value="true" />
<property name="proxyInterface" value="javax.sql.DataSource" />
</bean>



<bean id="txManager"
class="org.springframework.transaction.jta.JtaTransactionManager" />
<!--
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="springDataSource"/>
</bean>
-->


<bean id="fooService" class="foo.FooServiceImpl">

</bean>


<bean id="fooBaseTransactionProxy"

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="target">
<ref bean="fooService" />
</property>
<property name="transactionManager">
<ref bean="txManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="*">
PROPAGATION_NEVER,ISOLATION_READ_UNCOMMITTED,-java.lang.Exception
</prop>
</props>
</property>

</bean>
</beans>





If later I can figure out how to add these as files, I will.

Thanks for the help so far.

Josh S

unread,
Aug 15, 2008, 5:21:22 PM8/15/08
to KCJava
Jason-

I tried to copy what you had, by injecting the TransactionProxy on to
the service class. What I ended up with was the same problem.
Propagation was set to NEVER and it still committed the transaction.

Is it possible that I just don't understand how I am defining the
transactional states?





On Aug 15, 3:21 pm, "Jason Bedell" <jason.bed...@gmail.com> wrote:
> Attached is a spring container config we have in production for a fairly small site. This uses a transaction proxy as a transaction management aspect on a service tier.The transaction proxy is being injected with a Hibernate transaction manager but it could be a JTA manager if you wanted.I you want toshare your Spring container config, I'm sure the group (I) would be happy to look at it. Hope this helps.Jason Bedellhttp://www.jasonbedell.comhttp://blog.jasonbedell.comhttp://www.linkedin.com/in/jasonbedellhttp://twitter.com/jasonbedellhttp://del.icio.us/jasonbedellhttp://digg.com/users/jasonbedell-------- Original Message --------
> Subject: [kcjava] Re: Spring Help
> From: new...@att.net
> Date: Fri, August 15, 2008 3:03 pm
> To: KCJ...@googlegroups.com
>
> Have you looked at Spring's petstore example app?
> One thing that happened to us is we tried to convert some apps in piecemeal fashion, and we got similar results to yours. The original approach was to use IbatisDAO with programmatic transactions. Trying to convert over a little at a time resulted in a situation where we had two database connection pools, the IbatisSimpleDataSource and DBCP, with different parts of the code grabbing the database connection from a different pool, with results like what you describe.
> Newton 
>
> -------------- Original message from Josh S <jesm...@sbcglobal.net>: --------------
> >
> > I am working on a large scale J2EE project that I need some Spring
> > help on.
> >
> > We are currently using EJB's (Stateless Session) for the transaction
> > management component (CMT), and I am wanting to convert that to Spring
> > Transaction management, probably still JTA.
> >
> > The hope is that then I can leverage Spring to allow me to run tests
> > outside of the container if needed.
> >
> >
> > My problem seems to be configuring Spring correctly to control the
> > transactions. In some simple testing I am seeing transactions commit
> > when they shouldn't, and not commit when they should. Not sure if my
> > problem is related to my bean config for my business service,
> > transaction manager, data source, etc....
> >
> > I will happily post out any code anyone wants to see, but I am really
> > needing a good example of how to do Spring Managed transactions with
> > raw JDBC.
> >
> > Any help is appreciated.
> >
>
>  applicationContext.xml
> 20KViewDownload

new...@att.net

unread,
Aug 18, 2008, 10:19:22 AM8/18/08
to KCJava, Josh S
your dao shouldn't be getting the database connection itself. that's why it's not paying attention to your transactional annotations, you're going around behind Spring's back. You should extend a template class provided by spring, which knows where to get the database connection (from a threadlocal).

the sample apps are part of the regular Spring download. If you're not allowed to download this yourself ( :^(  ) go to whoever is and bug them for it. you want the file that says "-with-dependencies.zip".

there's also an article on onjava.com. it's pretty dated but might be helpful:
 http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html



-------------- Original message from Josh S <jesm...@sbcglobal.net>: --------------
> private static Hashtable dsTable = new
> Hashtable();
>
> static Connection getConnection(String name){
> Connection conn = null;
> DataSource ds = null;
> name = "springDataSource";
> try {
> if (dsTable.containsKey(name)){
> conn =
> DataSourceUtils.doGetConnection(dsTable.get(name));
> } else {
> ClassPathXmlApplicationContext context = new
> ClassPathXmlApplicationContext("applicationContext.xml");
> ds = (DataSource)context.getBean(name);
> conn = DataSourceUtils.doGetConnection(ds);
> }
> //conn.setAutoCommit(false);
>
> System.out.println("The connection is transactional " +
> DataSourceUtils.isConnectionTransactional(conn, ds));
>
> } catch (SQLException e){
> e.printStackTrace();
> }
>
> return conn;
> }
>
> }
>
> applicationContext.xml
>
>
>
>
> class="true" />
>
>
> class="org.springframework.jndi.JndiObjectFactoryBean">
>
> value="java:jdbc/SpringDB" />
>
>
>
>
>
>
>
>
> class="org.springframework.transaction.jta.JtaTransactionManager" />
>
>
>
>
>
>
>
>
>
>
> class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
> abstract="true">
>
>
>
>
>
>
>
>
>
>
> PROPAGATION_NEVER,ISOLATION_READ_UNCOMMITTED,-java.lang.Exception
>
>
>
>
>
>
>
>
>
>
>
> If later I can figure out how to add these as files, I will.
>
> Thanks for the help so far.
>
>
>
>
>
>
>
> On Aug 15, 3:40 pm, Josh S wrote:
> > I haven't looked that yet, in part because I am struggling to find it.
> > My office won't let us download things (even zip files) from the
> > internet. So I am stuck using what they have already pulled down. That
> > doesn't seem to include any example apps.
> >
> > On Aug 15, 3:03 pm, newt...@att.net wrote:
> >
> > >  Have you looked at Spring's petstore example app?
> >
> > > One thing that happened to us is we tried to convert some apps in piecemeal
> fashion, and we got similar results to yours. The original approach was to use
> IbatisDAO with programmatic transactions. Trying to convert over a little at a
> time resulted in a situation where we had two database connection pools, the
> IbatisSimpleDataSource and DBCP, with different parts of the code grabbing the
> database connection from a different pool, with results like what you describe.
> >
> > > Newton
> >
> > >   -------------- Original message from Josh S :
> --------------
> >
> > > > I am working on a large scale J2EE project that I need some Spring
> > > > help on.
> >
> > > > We are currently using EJB's (Stateless Session) for the transaction
> > > > management component (CMT), and I am wanting to convert that to Spring
> > > > Transaction management, probably still JTA.
> >
> > > > The hope is that then I can leverage Spring to allow me to run tests
> > > > outside of the container if needed.
> >
> > > > My problem seems to be configuring Spring correctly to control the
> > > > transactions. In some simple testing I am seeing transactions commit
> > > > when they shouldn't, and not commit when they should. Not sure if my
> > > > problem is related to my bean config for my business service,
> > > > transaction manager, data source, etc....
> >
> > > > I will happily post out any code anyone wants to see, but I am really
> > > > needing a good example of how to do Spring Managed transactions with
> > > > raw JDBC.
> >
> > > > Any help is appreciated.
> >
> >

Josh S

unread,
Aug 18, 2008, 10:42:25 AM8/18/08
to KCJava
I don't understand how it matters if the DAO is getting the connection
itself? Actually it is going through a class (ConnManager) that is
doing a SpringBean lookup for the DataSource, and using the
DataSourceUtils class to get the connection. I can even run the
"isConnectionTransactional" check on the returned transaction and it
works fine.


My app is to big to change all of the DAO's we have or to fully break
the pattern of how it is looking up the DAO. But I have done checks
with system outs and the DAO is working against a proxied copy of the
datasource and connection. They are spring aware objects that are
doing the actual query. At this point I need a way that will have as
little impact as possible on DAO's and service classes. Currently my
app goes

EJB > Business Service > Persistentce Service (to aggregate DAO calls)
> DAO.

The EJB is just for transaction management. I want to replace it with
Spring, and not replace anything else. Is this possible, or do you
really have to use all of Spring to make this happen?












On Aug 18, 9:19 am, newt...@att.net wrote:
> your dao shouldn't be getting the database connection itself. that's why it's not paying attention to your transactional annotations, you're going around behind Spring's back. You should extend a template class provided by spring, which knows where to get the database connection (from a threadlocal).
>
> the sample apps are part of the regular Spring download. If you're not allowed to download this yourself ( :^(  ) go to whoever is and bug them for it. you want the file that says "-with-dependencies.zip".
>
> there's also an article on onjava.com. it's pretty dated but might be helpful:
>  http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html
>
>  -------------- Original message from Josh S <jesmit...@sbcglobal.net>: --------------
> >             class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
>
> >    -->

new...@att.net

unread,
Aug 18, 2008, 11:19:39 AM8/18/08
to KCJava, Josh S
your code (the TestDao) isn't going through the transaction manager, that's the missing piece. sure, your connection is participating in a transaction, it's just not the transaction you want.

as for "do you really have to use all of spring": it may not be as big a task as you think. it mostly consists of ripping out boilerplate from your code and letting spring do the work for you. But first you really do need to check out some examples and develop a level of comfort with it.

also have you looked at EJB3, or is that what you're using now?


 
-------------- Original message from Josh S <jesm...@sbcglobal.net>: --------------
> >  -------------- Original message from Josh S :

Josh S

unread,
Aug 18, 2008, 2:26:10 PM8/18/08
to KCJava
I am really just trying to get comfortable with it in my test app. If
the problem is that my testDAO isn't going through the Transaction
Manager, then how do I fix that?

I am in a position where it seems like all of the examples I have
found from Spring focus on the injection only part. You let Spring
create your business service and inject the needed DAO into that, and
Spring creates your DAO and injects your DataSource into that. It
isn't a huge effort to do, as most of that is boilerplate, unless you
have an existing app and in the neighborhood of 100 files that you
would have to refactor and test. Bottom line is that it isn't
practical right now, and it leaves me just a tied to a framework as
EJB does now. I am trying to stay more independent of that.

Spring documentation says you should be able to get it's tx management
stuff to work with existing legacy JDBC, but never shows how to do
it. That's what I need.

I haven't looked at EJB 3, becuase my office uses JBoss for Dev, but
WebSphere 6.1 for prod. We haven't gotten the add-on for WebSphere 6.1
that allows it to support J2EE 1.5 (and EJB3). So unless they do a
massive upgrade on the server farm in the next 6 months, EJB3 is out
of the question.


Really, I am currently using EJB 2.1 (Stateless session beans) for my
Tx Management. And they are just overkill. The bring in xDoclet, and a
large footprint that I am trying to eliminate with Spring.

Does anyone know how to wire existing raw JDBC work to a Spring
Transaction management?





On Aug 18, 10:19 am, newt...@att.net wrote:
> your code (the TestDao) isn't going through the transaction manager, that's the missing piece. sure, your connection is participating in a transaction, it's just not the transaction you want.
>
> as for "do you really have to use all of spring": it may not be as big a task as you think. it mostly consists of ripping out boilerplate from your code and letting spring do the work for you. But first you really do need to check out some examples and develop a level of comfort with it.
>
> also have you looked at EJB3, or is that what you're using now?
>
>  -------------- Original message from Josh S <jesmit...@sbcglobal.net>: --------------
> ...
>
> read more »

new...@att.net

unread,
Sep 12, 2008, 10:14:45 AM9/12/08
to KCJ...@googlegroups.com
 I think this is a really interesting question, I don't know enough to answer it.
Spring has the agenda of trying to reduce dependence on distributed transactions, so enabling this kind of thing is not a priority with them, but it seems like something that could be done. might be a lot of work though. if you find a solution I would be interested in hearing about it.

It surprises me your WAS admin won't install the EJB3.0 feature pack.

-------------- Original message from Josh S <jesm...@sbcglobal.net>: --------------
> >  -------------- Original message from Josh S :

Gregg Bolinger

unread,
Sep 12, 2008, 1:57:48 PM9/12/08
to KCJ...@googlegroups.com
This thread might give you some insight on using transactions with legacy JDBC code.

http://forum.springframework.org/showthread.php?t=35999&highlight=legacy

It is inline with my own assumptions in that as long as Spring has wrapped the connection with its transaction support you should just be able to pass the connection/datasource to your JDBC code and let Spring AOP take care of the rest.  However, I've never tried it.  So these are merely assumptions.

Gregg
Gregg Bolinger
Reply all
Reply to author
Forward
0 new messages