Описание: Исключение говорит мне, что транзакция доступна только для чтения; 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
Я изменил одну сессию собственности. Задача решена. http://stackoverflow.com/a/13726254/159837 –
getHibernateTemplate() getSessionFactory() getCurrentSession() setFlushMode (FlushMode.AUTO)...; –