只读模式下不允许写操作 - 持久化时出现问题

Posted

技术标签:

【中文标题】只读模式下不允许写操作 - 持久化时出现问题【英文标题】:Write operations are not allowed in read-only mode - Issue while persisting 【发布时间】:2014-10-03 01:05:47 【问题描述】:

我在尝试将对象保存到数据库时遇到了以下错误。我尝试了提到here1 和here2 的解决方案,但没有用。我关注的是tutorial,但唯一的区别是 Spring 和 Hibernate 的版本。

我可以直接使用 SessionFactory 持久化对象,但如果我尝试使用 HibernateDaoSupport 会失败并出现以下错误

spring.xml

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
    <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
    <property name="username" value="system" />
    <property name="password" value="xxx" />
</bean>

<context:annotation-config/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="packagesToScan" value="org.sri.sphiber.model"></property>
    <property name="hibernateProperties">
        <props>
            <prop key="dialect">org.hibernate.dialect.OracleDialect</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>



<bean id="customerDAOImpl" class="org.sri.sphiber.dao.CustomerDAOImpl">
    <property name="hibernateTemplate" ref="hibernateTemplate" />
</bean>

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

CustomerDAOImpl.java

public class CustomerDAOImpl extends HibernateDaoSupport 

    public boolean insertCustomer(Customer cust)

        try 
            getHibernateTemplate().saveOrUpdate(cust);
         catch (DataAccessException e) 
            e.printStackTrace();
            return false;
        
        return true;
    


使用调用它。

public class MainClass 

    public static void main(String[] args) 


            ApplicationContext appContext = new ClassPathXmlApplicationContext("spring.xml");
            CustomerDAOImpl hdi=appContext.getBean("customerDAOImpl",CustomerDAOImpl.class);


            Customer customer=new Customer();
            customer.setCustomerName("Sri");

            boolean isUpdated = hdi.insertCustomer(customer);

    



错误信息。

Aug 10, 2014 12:45:52 AM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000232: Schema update complete
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
    at org.springframework.orm.hibernate4.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1135)
    at org.springframework.orm.hibernate4.HibernateTemplate$16.doInHibernate(HibernateTemplate.java:684)
    at org.springframework.orm.hibernate4.HibernateTemplate.doExecute(HibernateTemplate.java:340)
    at org.springframework.orm.hibernate4.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:308)
    at org.springframework.orm.hibernate4.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:681)
    at org.sri.sphiber.dao.CustomerDAOImpl.insertCustomer(CustomerDAOImpl.java:16)
    at org.sri.sphiber.main.MainClass.main(MainClass.java:26)

版本详情:

Spring version : spring-framework-4.0.6.RELEASE
Hibernate Version : hibernate-release-4.3.5.Final
Database : Orcale 11g

【问题讨论】:

【参考方案1】:

在配置文件中

进行更改:-

@Configuration
@EnableTransactionManagement   <-----Put this line
public PersistenceConfig
//your code

(或)

@Bean
@Autowired
public HibernateTemplate getHibernateTemplate(SessionFactory session) 
        HibernateTemplate hb = new HibernateTemplate();
        hb.setCheckWriteOperations(false);
        hb.setSessionFactory(session);
        return hb;
    

【讨论】:

【参考方案2】:

您缺少 TransactionManager 定义,请参阅http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/transaction.html

[更新] 以前我是用手机写的,所以很难提供细节,这是你需要做的:

    Spring xml 配置:

    <tx:annotation-driven/>
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
    </bean> 
    

    在 CustomerDaoImpl.insertCustomer 方法中添加 @Transactional 注解

现在您的代码应该可以工作了。 请注意 @Transactional 注解应该用在服务层,而不是像本例那样用在 DAO 层。 @Transactional 注释告诉 spring 创建代理,该代理使用方面“包装”带有事务的注释方法。

【讨论】:

我按照您的建议添加了 TransactionManager(编辑了问题),但仍然出现相同的错误,我完全遵循这一点。你能解释一下吗?谢谢。 它就像魅力一样工作,它正在寻找一个名为 transactionManager 而不是 txManager 的 bean。让我再看一下文档。我想我想念理解它的工作方式。 :) 非常感谢 如果你以编程方式配置你的spring应用,你可以添加@EnableTransactionManagement注解,它相当于。所以只需将@EnableTransactionManagement 注释添加到您的@Configuration 注释类。

以上是关于只读模式下不允许写操作 - 持久化时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

只读模式下不允许写操作(FlushMode.MANUAL):使用 grails hibernate

AngularJS ie 11 中严格模式下不允许对只读属性赋值

核心数据 - 删除持久存储时出现死锁

PersistentObjectException:分离的实体传递给持久化-第二次运行方法时出现此异常

JSLint:设置控制台时出现只读错误,即使它设置为可写全局

48-Docker-多容器数据共享及持久化