Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Committ problems with @Transactional annotations

  1. #1

    Default Commit problems with @Transactional annotations

    Hello folks,

    I am currently trying to implement annotation-based transactions with Spring 2.x and Hibernate with Oracle. So far I configured the <tx:annotation-driven>-tag and the corresponding transaction manager:

    PHP Code:
        <!-- transaction manager -->
        <
    bean id="transactionManager"
            
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <
    property name="dataSource" ref="dataSource"/>
        </
    bean>

        <
    bean id="sessionFactory"
            
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <
    property name="configLocation"
                
    value="classpath:hibernate.cfg.xml" />
        </
    bean
    Every service class implementation has a @Transactional annotation attached:

    Code:
    @Transactional
    public class UserServiceImpl ......
    All read operations have "@Transactional(readOnly=true)".

    When using the services to persist some entity there seems to be no problem:

    Code:
    Hibernate: insert into SCHEMA.USER ...........
    ... however the data is not committed to the database. There is no new entry! Where to configure the commit command?
    Last edited by Rapthor; Jul 18th, 2007 at 02:42 PM.

  2. #2
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,425

    Default

    If you are using Hibernate, shouldn't you be using the HibernateTransactionManager instead? Also you've marked the transaction as readOnly but you want to commit?
    Last edited by karldmoore; Aug 27th, 2007 at 04:29 PM.
    Barracuda Networks SSL VPN Lead Developer
    http://pramatr.wordpress.com
    http://twitter.com/karldmoore
    http://www.linkedin.com/in/karldmoore
    Any postings are my own opinion, and should not be attributed to my employer or clients.

  3. #3

    Default

    Quote Originally Posted by karldmoore View Post
    If you are using Hibernate, shouldn't you be using the HibernateTransactionManager instead? Also you've marked the transaction as readOnly but you want to commit?
    The problem is I cannot use HibernateTransactionManager since third party webapps will use my services and they cannot see Hibernate's ConnectionWrapper interface from their classloaders (which seems to be an integral part of Hibernate's Transaction strategy). Using the configuration I described above seems to work partly ... however actions are not committed.

    ReadOnly is only used for "find*-methods". Methods like "makePersistent" have NO "@Transactional(readOnly=true)"-attribute. They fall back to the annotation defined for the service-class (@Transactional). I have done this following the Spring documentation.

    In fact my services are using DAOs which themselves have the SessionFactory you can see above. Is that useless concerning the configuration I made so far? (Using "DataSourceTransactionManager" instead of "HibernateTransactionManager"?)

    Sorry to bother you with questions like that, but the problem with the ConnectionWrapper-interface spoiled me for tooooooooo long. So I really really hope that discarding Hibernate's Transaction Manager can solve my problems.

    Thanks in advance ...

    (I am about to try using "<tx:advice id="txAdvice" transaction-manager="transactionManager">....". I think I will have the same committ-problem with that approach.)

  4. #4

    Default

    PHP Code:
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <
    tx:attributes>
                <
    tx:method name="find*" read-only="true" />
                <
    tx:method name="*" />
            </
    tx:attributes>
        </
    tx:advice>

        <
    aop:config>
            <
    aop:pointcut id="serviceMethods"
                
    expression="execution(* com.mycomapny.service.*.*(..))" />
            <
    aop:advisor advice-ref="txAdvice"
                
    pointcut-ref="serviceMethods" />
        </
    aop:config
    "<tx:advice..." doesn't work either. The service methods being called by the second webapp are not executed within a transaction. Even though calls from within the first webapp that provides the services are in deed transactionized.

    Code:
    org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    	at org.springframework.orm.hibernate3.AbstractSessionFactoryBean$TransactionAwareInvocationHandler.invoke(AbstractSessionFactoryBean.java:299)

  5. #5
    Join Date
    Sep 2004
    Posts
    1,086

    Default

    Quote Originally Posted by Rapthor View Post
    Sorry to bother you with questions like that, but the problem with the ConnectionWrapper-interface spoiled me for tooooooooo long. So I really really hope that discarding Hibernate's Transaction Manager can solve my problems.
    To use Hibernate and transactions you need HibernateTransactionManager, and there is no way about it.

    But, you could try to explain us the problem with Hibernate ConnectionWrappers - is sounds like something that should be fairly easy to work around.

  6. #6

    Default

    Quote Originally Posted by dejanp View Post
    To use Hibernate and transactions you need HibernateTransactionManager, and there is no way about it.

    But, you could try to explain us the problem with Hibernate ConnectionWrappers - is sounds like something that should be fairly easy to work around.
    I posted a thread on this topic a few weeks ago but got no response that solved the problem:

    http://forum.springframework.org/sho...781#post128781

    (See the picture tomcat.jpg in the 3rd post. It describes best what my current situation is.)

    I even tried to use <tx:advice> like described above with HibernateTransactionManager and got the same ConnectionWrapper exception.

  7. #7
    Join Date
    Sep 2004
    Posts
    1,086

    Default

    You can't reference child classloaders from the parent classloaders:

    Class A (Classloader 1)
    Class B (Classloader 2)
    Class C (Classloader 1)

    You can't have A->B->C. You can put B in classloader 1 or you can put C in classloader 2.

    In other words: pack your jar with Hibernate jars. No matter if both are in the shared lib or in the web-app, but they need to be together.

    Btw, I'd say using a shared lib is not a realistic solution. It creates a hard dependency between application version and your library version. When you change the library all apps _must_ be rewritten at the same time, you need to stop the server, change the library, redeploy all the apps, restart the server. Not very nice and, at larger scale, absolutely unfeasible.

  8. #8

    Default

    Seems as if I will have to put the webapps together to avoid the bad style you mentioned. Unfortunately I am going to raise another bad style to put all of the persistence, application and ui components into one single webapp. I would have like to seperate persistence and application from ui without using any EJB application server.

    Nevertheless, thanks for the advice!

  9. #9
    Join Date
    Sep 2004
    Posts
    1,086

    Default

    By putting a jar file in one or the other classloader you do not separate anything imo.

    The separation is done on the application design level, not on the deployment/packaging level. If your application is well designed, so that it logically separates differenent concerns then the packaging doesn't really matter and is usually done in the way that allows most flexibility (what that means is up to your needs).

  10. #10

    Default

    Quote Originally Posted by dejanp View Post
    By putting a jar file in one or the other classloader you do not separate anything imo.

    The separation is done on the application design level, not on the deployment/packaging level. If your application is well designed, so that it logically separates differenent concerns then the packaging doesn't really matter and is usually done in the way that allows most flexibility (what that means is up to your needs).
    I was searching for a way to keep transactions within one webapp in order to provide "Value Objects" (or "Transfer Objects") at the surface. I am really surprised about not being able to isolate all the transaction stuff from other webapps. I still wonder if there is a way to do transactions within my logic and persistence webapp only and have another webapp access only the "Value Objects" that represent the results of those transactions.

    I think of dynamically changing the UI webapp that handles "Value Objects" without having to shut down the whole webapp that contains the logic stuff. Furthermore I am about to create another webservice application that should use the Value Objects just like the UI webapp should do.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •