IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Spring Java Discussion :

UncategorizedSQLException: Hibernate flushing


Sujet :

Spring Java

  1. #1
    Membre Expert Avatar de DoubleU
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 106
    Par défaut UncategorizedSQLException: Hibernate flushing
    Désolé pour le titre aussi peu expressif, mais je ne savais pas trop comment appeler ce post ^^

    Bref, voila ma situation: je suis en train de tester Spring/hibernate dans une petite appli et j'ai un problème au moment de faire les tests JUnits de mes DAO.

    la conf de Spring
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    <?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.5.xsd">
     
    	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
    	    <property name="driverClassName" value="org.postgresql.Driver"/>
    	    <property name="url" value="jdbc:postgresql://localhost/dog"/>
    	    <property name="username" value="postgres"/>
    	    <property name="password" value="******"/>
    	</bean>
     
    	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory" ref="sessionFactory" />
    	</bean>
     
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    	    <property name="dataSource" ref="dataSource"/>
    	    <property name="mappingResources">
    	        <list>
    	            <value>./fr/dog/bean/Race.hbm.xml</value>
    	        </list>
    	    </property>
    	    <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
                    <prop key="hibernate.use_outer_join">true</prop>
    			</props>
    	    </property>
    	</bean>
     
    	<!-- transaction interceptor -->
    	<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
    		<property name="transactionManager" ref="transactionManager"/>
    		<property name="transactionAttributes">
    			<props>
    				<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
    				<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    				<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
    				<prop key="save*">PROPAGATION_REQUIRED</prop>
    			</props>
    		</property>
    	</bean>
     
    	<!-- autoproxy -->
    	<bean id="transactionBeanNameProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    		<property name="beanNames"><value>*DAO</value></property>
    		<property name="interceptorNames">
    		<list>
    			<value>transactionInterceptor</value>
    		</list>
    		</property>
    	</bean>
     
     
    	<bean id="raceDAO" class="fr.dog.dao.RaceDAO">
    	    <property name="sessionFactory">
    	        <ref bean="sessionFactory"/>    
    	    </property>
    	</bean>
     
     
    </beans>


    Mon DAO:
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    public class RaceDAO implements IRaceDAO {
     
    	private SessionFactory  sessionFactory;
     
    	/**
             * @return the sessionFactory
             */
    	public SessionFactory getSessionFactory() 
    	{
    		return sessionFactory;
    	}
     
    	/**
             * @param sessionFactory the sessionFactory to set
             */
    	public void setSessionFactory(SessionFactory sessionFactory) 
    	{
    		this.sessionFactory = sessionFactory;
    	}
     
            // ....
     
    	@Override
    	public void update(Race race) 
    	{
    		sessionFactory.getCurrentSession().update(race);
    	}
    }

    ma classe de Test:
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    public class TestRace extends TestCase{
     
    	private IRaceDAO dao;
    	private AbstractApplicationContext factory;
     
    	public void setUp()
    	{
    		factory = new ClassPathXmlApplicationContext("spring-hibernate.xml");
    		dao = (IRaceDAO)factory.getBean("raceDAO");
     
    		SessionTransactionManager.start((SessionFactory)factory.getBean("sessionFactory"));	
    	}
     
    	public void tearDown()
    	{
    		SessionTransactionManager.stop((SessionFactory)factory.getBean("sessionFactory"));
    	}
     
    	public void testUpdate()
    	{
    		Race a = new Race("Elfe");
    		Long id = dao.save(a);	
    		a.setNom("Night Elf");
    		dao.update(a);
    		//((SessionFactory)factory.getBean("sessionFactory")).getCurrentSession().flush();
    		Race b = dao.get(id);		
    		assertEquals("Night Elf", b.getNom());	
    	}

    J'ai lu ailleurs qu'en fait, comme je test hors du container, je dois gérer mes sessions moi même donc j'ai repiqué un code qui à l'air de fonctionner pour les autres tests:
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class SessionTransactionManager
    {
     
    	public static void start(SessionFactory sessionFactory)
        {
    		Session session = SessionFactoryUtils.getSession(sessionFactory, true);
    		TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
        }
     
    	public static void stop (SessionFactory sessionFactory)
        {
    		SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
    		SessionFactoryUtils.releaseSession(sessionHolder.getSession(), sessionFactory);
    	}
    }

    Et donc mon problème, c'est que quand je passe mon test de update, j'ai cette exception:
    Citation Envoyé par la console
    org.springframework.jdbc.UncategorizedSQLException: Hibernate flushing: Could not execute JDBC batch update; uncategorized SQLException for SQL [update race set nom=? where id=?]; SQL state [null]; error code [0]; L'élément du batch 0 update race set nom=Night Elf where id=252 a été annulé. Appeler getNextException pour en connaître la cause.; nested exception is java.sql.BatchUpdateException: L'élément du batch 0 update race set nom=Night Elf where id=252 a été annulé. Appeler getNextException pour en connaître la cause.
    Citation Envoyé par le logger
    1478 [main] ERROR org.hibernate.util.JDBCExceptionReporter - ERROR: transaction is read-only
    1478 [main] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session

    Et je dois dire que je ne suis pas sûr de comprendre pourquoi... Si je décommente la ligne qui fait le flush, tout se passe bien mais pour quelle raison? Est-ce que ca a un rapport avec la conf de Spring qui met PROPAGATION_REQUIRED,readOnly sur les methodes get* ?

    Merci d'avance

  2. #2
    Invité de passage
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1
    Par défaut Gerer le flush de la session explicitement
    Bonjour,

    Tu as raison, il faut dans la méthode setup(), (réalisant l'isolation de ta méthode de test) gérer explicitement le flush de la session, afin de réaliser la synchronisation avec la base. Pour cela, avant de réaliser le binding de la transaction, essaies de faire un session.setFlushMode(FlushMode.AUTO).

    Voila,
    bon w-e.

Discussions similaires

  1. Spring/Hibernate --> utilisation de flush
    Par stof dans le forum Hibernate
    Réponses: 4
    Dernier message: 03/10/2011, 17h32
  2. hibernate, flush ne faisant pas d'insert..
    Par Djef-69 dans le forum Persistance des données
    Réponses: 3
    Dernier message: 26/02/2011, 20h25
  3. Réponses: 9
    Dernier message: 21/03/2009, 22h12
  4. [Data] Spring Hibernate et Flush order
    Par trungsi dans le forum Spring
    Réponses: 5
    Dernier message: 17/02/2009, 09h13
  5. [JDO]Hibernate : Mapping d'un champ auto-incrémenté
    Par brice.antoine dans le forum Hibernate
    Réponses: 4
    Dernier message: 02/04/2004, 10h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo