2010-10-06 5 views
6

Zusammenfassung: die Ausnahme sagt mir, dass die Transaktion schreibgeschützt ist; Ein Debug-Ausdruck scheint darauf hinzudeuten, dass ich mich nicht im schreibgeschützten Modus befinde.HIbernate InvalidDataAccessApiUsageException - schreibgeschützter Modus

Klassen für Internet-Publishing bearbeitet - tut mir leid, wenn ich etwas falsch eingegeben habe, aber das ist der Jist des Codes, der mir Probleme gibt. saveOrUpdate funktioniert, wenn es für andere Objekttypen aufgerufen wird, aber nicht für dieses Objekt. Ich habe die println zu saveOrUpdate hinzugefügt, während ich debugging. Ich habe die abstrakte Klasse nicht geschrieben, ich versuche nur, sie zu benutzen (und debugge sie jetzt).

Relevante Ausgabe unter dem Code. Ich bin mir nicht sicher, wo ich von hier aus hingehen soll.

Update nach der Untersuchung: Ich habe auch in der Mitte einige Updates zu der Spring Config getan und ein Kollege wies darauf hin, dass eine Methode, die ich updateAParameter nannte von Frühling auf eine Art und die gebrochene Methode war es verwendet auf eine andere Art. Leider ist der gebrochene Weg der Weg, auf den ich hin wollte.

Also das Problem, wie ich es jetzt verstehe, ist, dass, wenn ich das DataObjectDAOImpl "manuell" in einer Methode instanziiert, indem Sie eine Bohne erhalten, dann erlaubt es mir, zurück zu Hibernate korrekt zu schreiben. Wenn ich eine Klassenvariable für diese Bean mit spring definiere, damit ich sie nicht in jeder Methode instanziieren muss, tritt die InvalidDataAccessApiUsageException auf, wenn ich auf eine Methode zugreife, die versucht, in Hibernate zu schreiben, obwohl sie sich nicht meldet schreibgeschützter Modus Mein Kollege hatte eine Theorie zu diesem Thema, aber ich verstand nicht, was er sagen wollte - etwas über das Extrahieren einer Schnittstelle aus der 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); 
} 
} 

und hier ist relevant Bohne aus der Feder Config

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

hier ist die DAOImpl, das gleich für die alte und neue Art und Weise ist

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); 
    }   
} 

Ausgang aus dem App-Server:

 [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

ich die Sitzung Eigenschaft geändert. Problem gelöst. http://stackoverflow.com/a/13726254/159837 –

+0

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

Antwort

3

Th Das eine mögliche Problem, das ich hier sehen kann, ist, dass Sie @Transactional Methode aus der gleichen Bean aufrufen. Ich bin nicht sicher, wie es mit Ihrer Ausnahme in Verbindung stehen kann, aber da die deklarative Transaktionsverwaltung von Spring über einen proxybasierten AOP implementiert wird, bedeutet dies, dass diese Anmerkung nicht wirksam wird.

Siehe auch:

+0

Danke. Ich habe den gleichen Fehler bekommen. Ich habe '@Transactional (readOnly = false)' zu meiner Methode hinzugefügt, und es funktioniert jetzt. –

+0

Das war für mich fast 2,5 Jahre nach der Antwort sehr hilfreich. Vielen Dank, @axtavt. – Sid

Verwandte Themen