2010-10-06 3 views
6

Описание: Исключение говорит мне, что транзакция доступна только для чтения; debug println, похоже, указывает, что я не в режиме только для чтения.HIbernate InvalidDataAccessApiUsageException - режим только для чтения

Занятия отредактированы для публикации в Интернете - извините, если я что-то заполонил, но это и есть суть кода, дающего мне проблемы. saveOrUpdate работает при вызове других типов объектов, но не на этом. Я добавил println для сохраненияOrUpdate, поскольку я отлаживал. Я не писал абстрактный класс, я просто пытаюсь его использовать (и теперь отлаживаю его).

Релевантный выход под кодом. Не уверен, куда идти отсюда.

Обновление после расследования: Я также был посредине внесения некоторых изменений в конфигурацию пружины, и коллега указал, что один из методов, который я назвал updateAParameter, использовал весной одним способом, а сломанный метод использовал его другим способом. К сожалению, сломанный путь - это то, к чему я пытался добраться.

Так что проблема, как я теперь понимаю, заключается в том, что если я создам экземпляр DataObjectDAOImpl «вручную» в методе, получая bean-компонент, он позволяет мне корректно записывать обратно в Hibernate. Если я использую Spring для установки переменной класса для этого компонента, поэтому мне не нужно создавать его в каждом методе, тогда исключение InvalidDataAccessApiUsageException возникает, когда я обращаюсь к методу, который пытается записать в Hibernate, несмотря на то, что он сообщает, что он не находится в только для чтения. У моей коллеги была теория по этой теме, но я не понимал, что он пытался сказать - что-то об извлечении интерфейса из 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); 
} 
} 

и здесь уместно компонента из пружинной конфигурации

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

здесь является DAOImpl, который является одинаковым для старого и нового пути

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

Выход из сервера приложений:

 [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

Я изменил одну сессию собственности. Задача решена. http://stackoverflow.com/a/13726254/159837 –

+0

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

ответ

3

Th Единственная возможная проблема, которую я вижу здесь, заключается в том, что вы вызываете метод @Transactional из одного и того же компонента. Я не уверен, как это может быть связано с вашим исключением, но поскольку декларативное управление транзакциями Spring реализовано через AOP на основе прокси, это означает, что эта аннотация не вступает в силу.

Смотрите также:

+0

Спасибо. Я получал ту же ошибку. Я добавил '@Transactional (readOnly = false)' моему методу, и теперь он работает. –

+0

Это было действительно полезно для меня почти через 2,5 года после того, как вы отправили ответ. Спасибо тонну, @axtavt. – Sid

Смежные вопросы