2010-10-06 13 views
6

Riepilogo: l'eccezione indica che la transazione è di sola lettura; un debug println sembra indicare che non sono in modalità di sola lettura.HIbernate InvalidDataAccessApiUsageException - modalità di sola lettura

Classifiche modificate per la pubblicazione su Internet - scusate se ho digitato male qualcosa ma questo è il jist del codice che mi dà problemi. saveOrUpdate funziona quando viene richiamato su altri tipi di oggetto ma non su questo. Ho aggiunto println per salvareOrUpdate mentre eseguivo il debug. Non ho scritto la classe astratta, sto solo cercando di usarlo (e ora lo faccio il debug).

Uscita pertinente sotto il codice. Non so da dove andare.

Aggiornamento dopo un'indagine: sono stato anche nel bel mezzo di fare alcuni aggiornamenti alla configurazione primavera e un collega ha sottolineato che un metodo ho chiamato updateAParameter dalla stava usando primavera in un modo, e il metodo di rotta stava usando in un altro modo. Sfortunatamente la via spezzata è il modo in cui stavo cercando di arrivare.

Quindi il problema, come ora capisco, è che se istanziato il DataObjectDAOImpl "manualmente" in un metodo ottenendo un bean, allora mi consente di riscrivere correttamente Hibernate. Se uso spring per impostare una variabile di classe per quel bean, quindi non devo istanziarlo in ogni metodo, quindi InvalidDataAccessApiUsageException si verifica quando accedo a un metodo che tenta di scrivere su Hibernate, nonostante il fatto che non stia riportando modalità di sola lettura. Il mio collega aveva una teoria su questo argomento ma non capivo cosa stesse cercando di dire - qualcosa sull'estrazione di un'interfaccia da SampleClass.

// Old way that works. 
public class SampleClass { 
public void someMethod { 
ApplicationContext ac = ApplicationContextFactory.getApplicationContext(); 
DataObjectDAOImpl dodi = ((DataObjectDAOImpl) ac.getBean("dodi")); 
//this works 
dodi.updateAParameter("foo", exampleDataObject); 
} 
} 

//New way that doesn't work but I would like it to. 
public class SampleClass { 
private DataObjectDAOImpl dodi = null; 
//'dodi' has getter and setter methods that I am not pasting here for simplicity 
public void someMethod {  
//causes Exception 
dodi.updateAParameter("foo", exampleDataObject); 
} 
} 

e qui è rilevante fagioli dal config primavera

<bean id="sampleclass" class="com.service.SampleClass" scope="prototype"> 
    <property name="dodi" ref="doDAOimpl"/> 
</bean> 

Ecco l'DAOImpl, che è lo stesso per il modo in cui vecchio e nuovo

public class DataObjectDAOImpl extends AbstractSpringDaoStuff { 

... 

public void updateAParameter(String parameter, DataObject do) { 
    do.setAParameter(parameter); 
    super.saveOrUpdate(do); 
} 

} 


public abstract class AbstractSpringDaoStuff extends HibernateDaoSupport { 

    ... 

    @Transactional(readOnly=false) 
    protected void saveOrUpdate(Object obj) { 
    System.out.println ("Read-only?: " + TransactionSynchronizationManager.isCurrentTransactionReadOnly()); 

     getHibernateTemplate().saveOrUpdate(obj); 
    }   
} 

uscita dal server app:

 [java] Read-only?: false 
    [java] - Method execution failed: 
    [java] org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition. 
    [java]  at org.springframework.orm.hibernate3.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1186) 
    [java]  at org.springframework.orm.hibernate3.HibernateTemplate$16.doInHibernate(HibernateTemplate.java:750) 
    [java]  at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419) 
    [java]  at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374) 
    [java]  at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:748) 
    [java]  at com.est.dao.AbstractSpringDaoStuff.saveOrUpdate(AbstractSpringDaoMDA.java:24) 
etc 
+0

ho cambiato la proprietà singola sessione. Problema risolto. http://stackoverflow.com/a/13726254/159837 –

+0

getHibernateTemplate() getSessionFactory() getCurrentSession() setFlushMode (FlushMode.AUTO)...; –

risposta

3

Th Un possibile problema che posso vedere qui è che stai chiamando il metodo @Transactional dallo stesso bean. Non sono sicuro di come possa essere correlato alla tua eccezione, ma poiché la gestione dichiarativa delle transazioni di Spring è implementata tramite AOP basato su proxy, significa che questa annotazione non ha effetto.

Consulta anche:

+0

Grazie. Stavo ottenendo lo stesso errore. Ho aggiunto '@Transactional (readOnly = false)' al mio metodo, e ora funziona. –

+0

Questo è stato molto utile per me quasi 2,5 anni dopo aver postato la risposta. Grazie mille, @axtavt. – Sid

Problemi correlati