tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
2
ZUGRIFFE
1340
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    yogitobi yogitobi ist offline Grünschnabel
    Registriert seit
    Mar 2009
    Beiträge
    2
    Hallo zusammen,
    ich mache gerade meine ersten Schritte mit Spring. Insbesondere interessiert mich
    das Transaction-Management. Als ersten Test wollte ich das Pattern
    "Service (Transaktions-geklammert) ruft DAOs auf" implementieren.
    Um den Rollback zu testen, habe ich eine explizite Fehlermethode programmiert.
    Leider kommt es nie zu einem Rollback.

    Ich hoffe, einige von euch Experten können mir helfen.
    Danke im Voraus.

    Gruß
    Tobias



    Hier sind die entsprechenden Code-Teile:


    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    
    public class SimpleDataDao extends HibernateDaoSupport {
     
        public SimpleData getSimpleData(Integer simpleDataId) {
            return (SimpleData) getHibernateTemplate().get(SimpleData.class,
                simpleDataId);
        }
     
        public Integer saveSimpleData(SimpleData simpleData) {
         Integer ret = (Integer) getHibernateTemplate().save(simpleData);
         return ret;
        }
        
        public void failingMethod() {
         if(true){
                 throw new RuntimeException("testing");
             }
        }
    }
     
    -----------------------------------------------------
     
    @Transactional  
    public class SimpleDataService  {
        private SimpleDataDao simpleDataDao;
     
        public void complexOp() {
        SimpleData sp = new SimpleData();
        sp.setName("dummy1");
        simpleDataDao.saveSimpleData(sp);
        simpleDataDao.failingMethod();
        }
      
        public SimpleDataDao getSimpleDataDao() {
            return simpleDataDao;
        }
     
        public void setSimpleDataDao(SimpleDataDao simpleDataDao) {
            this.simpleDataDao = simpleDataDao;
        }
    }
     
    -----------------------------------------------
    public class MainToTest {
     
        public static void main(String[] args) {
        try {
            ClassPathResource res = new ClassPathResource("applicationContext.xml");
            XmlBeanFactory factory = new XmlBeanFactory(res);
            SimpleDataService service = (SimpleDataService)factory.getBean("simpleDataService");
         
            service.complexOp();
        } catch (Exception e) {
            System.out.println(e);
        }
        }
    }

    Es ist übrigens egal ob ich die Exception abfange oder nicht. In beiden Fällen
    gibt es kein Rollback.




    Hier sind die Spring Konfigurationen:
    applicationContext.xml:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
           default-autowire="byType">
     
        <import resource="databaseContext.xml"/>
        <import resource="transactionContext.xml"/>
     
        <bean id="simpleDataDao" class="x.y.dao.SimpleDataDao">
            <property name="sessionFactory" ref="sessionFactory"/>
        </bean>
     
        <bean name="simpleDataService" class="x.y.service.SimpleDataService">
            <property name="simpleDataDao" ref="simpleDataDao"/>
        </bean>
    </beans>


    databaseContext.xml:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    
    <?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: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/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd"
        default-autowire="byType">
     
        <!-- Database -->
        <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="annotatedClasses">
                <list>
                    <value>x.y.domain.SimpleData</value>
                </list>
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                    <prop key="hibernate.hbm2ddl.auto">create</prop>
                    <prop key="hibernate.jdbc.batch_size">0</prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.format_sql">true</prop>
                    <prop key="hibernate.cache.use_second_level_cache">
                        false
                    </prop>
                    <!--prop key="hibernate.cache.use_second_level_cache">true</prop-->
                    <prop key="hibernate.cache.use_query_cache">false</prop>
                    <prop key="hibernate.autocommit">false</prop>
                    
                    <!--prop key="hibernate.cache.use_query_cache">true</prop-->
                    <prop key="hibernate.cache.provider_class">
                        net.sf.ehcache.hibernate.SingletonEhCacheProvider
                    </prop>
                </props>
            </property>
        </bean>
         
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
            <property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
            <property name="jdbcUrl" value="jdbc:oracle:thin:@kfcorcl10:1521:fact" />
            <property name="user" value="TS" />
            <property name="password" value="TS" />
        </bean>
    </beans>


    transactionContext.xml:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    <?xml version="1.0" encoding="UTF-8"?>
    <beans default-init-method="init" default-destroy-method="destroy" 
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        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">
           
         
        <bean id="transactionManager"
              class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory"/>
            <property name="dataSource" ref="dataSource"/> 
        </bean>
        
        <tx:annotation-driven transaction-manager="transactionManager"/>
    </beans>


    Logging:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    
    2009-03-23 10:10:14,184 DEBUG [com.mchange.v2.resourcepool.BasicResourcePool] - trace com.mchange.v2.resourcepool.BasicResourcePool@ef894ce [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@3c6833f2)
    2009-03-23 10:10:14,186 DEBUG [org.hibernate.tool.hbm2ddl.SchemaExport] - 
        drop table SimpleData
    2009-03-23 10:10:14,189 DEBUG [org.hibernate.tool.hbm2ddl.SchemaExport] - 
        drop sequence hibernate_sequence
    2009-03-23 10:10:14,190 DEBUG [org.hibernate.tool.hbm2ddl.SchemaExport] - 
        create table SimpleData (
            id int4 not null,
            commentary varchar(255),
            name varchar(255),
            primary key (id)
        )
    2009-03-23 10:10:14,247 DEBUG [org.hibernate.tool.hbm2ddl.SchemaExport] - 
        create sequence hibernate_sequence
    2009-03-23 10:10:14,249 INFO [org.hibernate.tool.hbm2ddl.SchemaExport] - schema export complete
    2009-03-23 10:10:14,249 DEBUG [com.mchange.v2.resourcepool.BasicResourcePool] - trace com.mchange.v2.resourcepool.BasicResourcePool@ef894ce [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@3c6833f2)
    2009-03-23 10:10:14,249 DEBUG [org.hibernate.impl.SessionFactoryImpl] - Checking 0 named HQL queries
    2009-03-23 10:10:14,249 DEBUG [org.hibernate.impl.SessionFactoryImpl] - Checking 0 named SQL queries
    2009-03-23 10:10:14,250 DEBUG [org.springframework.beans.factory.xml.XmlBeanFactory] - Finished creating instance of bean 'sessionFactory'
    2009-03-23 10:10:14,250 DEBUG [org.springframework.beans.factory.xml.XmlBeanFactory] - Finished creating instance of bean 'sessionFactory'
    2009-03-23 10:10:14,256 DEBUG [org.springframework.beans.factory.xml.XmlBeanFactory] - Invoking afterPropertiesSet() on bean with name 'simpleDataDao'
    2009-03-23 10:10:14,256 DEBUG [org.springframework.beans.factory.xml.XmlBeanFactory] - Invoking afterPropertiesSet() on bean with name 'simpleDataDao'
    2009-03-23 10:10:14,256 DEBUG [org.springframework.beans.factory.xml.XmlBeanFactory] - Finished creating instance of bean 'simpleDataDao'
    2009-03-23 10:10:14,256 DEBUG [org.springframework.beans.factory.xml.XmlBeanFactory] - Finished creating instance of bean 'simpleDataDao'
    2009-03-23 10:10:14,257 DEBUG [org.springframework.beans.factory.xml.XmlBeanFactory] - Finished creating instance of bean 'simpleDataService'
    2009-03-23 10:10:14,257 DEBUG [org.springframework.beans.factory.xml.XmlBeanFactory] - Finished creating instance of bean 'simpleDataService'
    2009-03-23 10:10:14,264 DEBUG [org.springframework.orm.hibernate3.SessionFactoryUtils] - Opening Hibernate Session
    2009-03-23 10:10:14,264 DEBUG [org.springframework.orm.hibernate3.SessionFactoryUtils] - Opening Hibernate Session
    2009-03-23 10:10:14,284 DEBUG [org.hibernate.impl.SessionImpl] - opened session at timestamp: 12377994142
    2009-03-23 10:10:14,286 DEBUG [org.hibernate.jdbc.AbstractBatcher] - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
    2009-03-23 10:10:14,286 DEBUG [org.hibernate.jdbc.ConnectionManager] - opening JDBC connection
    2009-03-23 10:10:14,286 DEBUG [com.mchange.v2.resourcepool.BasicResourcePool] - trace com.mchange.v2.resourcepool.BasicResourcePool@ef894ce [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@3c6833f2)
    2009-03-23 10:10:14,287 DEBUG [org.hibernate.SQL] - 
        select
            nextval ('hibernate_sequence')
    Hibernate: 
        select
            nextval ('hibernate_sequence')
    2009-03-23 10:10:14,295 DEBUG [org.hibernate.id.SequenceGenerator] - Sequence identifier generated: 1
    2009-03-23 10:10:14,295 DEBUG [org.hibernate.jdbc.AbstractBatcher] - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
    2009-03-23 10:10:14,296 DEBUG [org.hibernate.event.def.AbstractSaveEventListener] - generated identifier: 1, using strategy: org.hibernate.id.SequenceGenerator
    2009-03-23 10:10:14,303 DEBUG [org.springframework.orm.hibernate3.HibernateTemplate] - Eagerly flushing Hibernate session
    2009-03-23 10:10:14,303 DEBUG [org.springframework.orm.hibernate3.HibernateTemplate] - Eagerly flushing Hibernate session
    2009-03-23 10:10:14,303 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] - processing flush-time cascades
    2009-03-23 10:10:14,303 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] - dirty checking collections
    2009-03-23 10:10:14,304 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] - Flushed: 1 insertions, 0 updates, 0 deletions to 1 objects
    2009-03-23 10:10:14,304 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
    2009-03-23 10:10:14,305 DEBUG [org.hibernate.pretty.Printer] - listing entities:
    2009-03-23 10:10:14,305 DEBUG [org.hibernate.pretty.Printer] - x.y.domain.SimpleData{id=1, commentary=null, name=dummy1}
    2009-03-23 10:10:14,307 DEBUG [org.hibernate.jdbc.AbstractBatcher] - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
    2009-03-23 10:10:14,307 DEBUG [org.hibernate.SQL] - 
        insert 
        into
            SimpleData
            (commentary, name, id) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            SimpleData
            (commentary, name, id) 
        values
            (?, ?, ?)
    2009-03-23 10:10:14,308 DEBUG [org.hibernate.jdbc.AbstractBatcher] - Executing batch size: 1
    2009-03-23 10:10:14,311 DEBUG [org.hibernate.jdbc.AbstractBatcher] - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
    2009-03-23 10:10:14,311 DEBUG [org.springframework.orm.hibernate3.SessionFactoryUtils] - Closing Hibernate Session
    2009-03-23 10:10:14,311 DEBUG [org.springframework.orm.hibernate3.SessionFactoryUtils] - Closing Hibernate Session
    2009-03-23 10:10:14,311 DEBUG [org.hibernate.jdbc.ConnectionManager] - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
    2009-03-23 10:10:14,312 DEBUG [com.mchange.v2.resourcepool.BasicResourcePool] - trace com.mchange.v2.resourcepool.BasicResourcePool@ef894ce [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@3c6833f2)
    2009-03-23 10:10:14,312 DEBUG [org.hibernate.jdbc.ConnectionManager] - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
    java.lang.RuntimeException: testing
     

  2. #2
    Avatar von Oliver Gierke
    Oliver Gierke Oliver Gierke ist offline Mitglied Rubin
    Registriert seit
    Dec 2003
    Ort
    Mannheim
    Beiträge
    1.457
    Ich vermute du bekommst beim Lookup der Bean eine ungeproxierte Instanz zurück, d.h. eine Instanz ohne den Transaktionalen Proxy davor. Es scheint auch desweiteren so, dass überhaupt keine Transaktion ausgelöst wird. Was mich bei dem Ganzen etwas wundert, ist, dass beim Hochfahren des Context keine Exception fliegt. Lange Rede, kurzer Sinn...

    1. Führ mal für den Service ein Interface ein und mach den Lookup über diesen. Normalerweise muss man, wenn man direkt Klassen benutzt die Proxies mit CGLib erzeugen lassen (extra Einstellungen in der Config). Spring erzeugt nämlich per default Delegateproxies und keine Inheritanceproxies. Also: Interface mit der Businessmethode anlegen, deine Implementierung dieses implementieren lassen und beim Lookup auf das Interface casten.

    2. Dreh mal die Loglevels für das tx Package hoch... dann sieht man besser, was da Transaktional vor sich geht.

    Kleinigkeiten noch: Du brauchst den Umweg über dei BeanFactory nicht zu machen. ApplicationContext ctx = new ClassPathXmlApplicationContext("config.xml"); reicht.

    REINHAUN!
     
    In theory, there is no difference between theory and practice. In practice, there is!

    www.olivergierke.de

  3. #3
    yogitobi yogitobi ist offline Grünschnabel
    Registriert seit
    Mar 2009
    Beiträge
    2
    Danke, jetzt funktioniert es!

    Entscheidend war den ApplicationContext zu verwenden.

    Gruß
    Tobias
     

Ähnliche Themen

  1. Spring und Hibernate
    Von y0dA im Forum Enterprise Java (JEE, J2EE, Spring & Co.)
    Antworten: 0
    Letzter Beitrag: 21.10.09, 14:30
  2. Spring und Hibernate - Testen
    Von y0dA im Forum Enterprise Java (JEE, J2EE, Spring & Co.)
    Antworten: 4
    Letzter Beitrag: 28.05.08, 19:10
  3. DTO, Spring und Hibernate
    Von DerGrinsemann im Forum Java
    Antworten: 2
    Letzter Beitrag: 08.06.07, 11:41
  4. update - Hibernate, Spring
    Von DerGrinsemann im Forum Java
    Antworten: 1
    Letzter Beitrag: 31.05.07, 18:32
  5. Antworten: 4
    Letzter Beitrag: 05.07.05, 12:54

Stichworte