在只读模式下不允许执行Spring / Hibernate Write操作

时间:2015-01-16 00:03:16

标签: java spring hibernate

我已经阅读了关于同一主题的其他一些问题,但在我的情况下,我实际上没有指明任何内容。让我感到困惑的是我有另一个有效的电话。我没有指定任何交易,所以我不确定为什么这会成为一个问题。

当我尝试使用xssSave()(在底部的服务类中)时会发生这种情况,但是sqlInject(也在同一个类中)工作正常。据我所知,这些操作相同,只是一个有效,一个无效。

如果您想查看完整代码和/或自行查看,可以在GitHub(https://github.com/tenmilez/WebBilly)上找到。

Spring配置(拆分为3个文件):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--
    <import resource="recipeasy-aspects.xml" />
    -->
    <import resource="webbilly-data.xml"/>
    <import resource="webbilly-spring.xml"/>
    <import resource="webbilly-service.xml"/>


    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="order">
            <value>0</value>
        </property>
        <property name="mappings">
            <props>
                <prop key="welcome.htm">welcomeController</prop>
                <prop key="sqli.htm">SQLiController</prop>
                <prop key="xss.htm">XssController</prop>
            </props>
        </property>
    </bean>

    <bean id="paramResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
        <property name="paramName" value="method"/>
        <property name="defaultMethodName" value="onInitPage"/>
    </bean>

    <bean id="welcomeController" class="com.webbilly.web.WelcomeController"/>

    <bean id="SQLiController" class="com.webbilly.web.SQLiController">
        <property name="methodNameResolver" ref="paramResolver"/>
        <property name="sqliServices" ref="sqliServices"/>
    </bean>

    <bean id="XssController" class="com.webbilly.web.XssController">
        <property name="methodNameResolver" ref="paramResolver"/>
        <property name="sqliServices" ref="sqliServices"/>
    </bean>
</beans>

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"

       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean id="sqliServices" class="com.webbilly.service.SQLiServices">
        <property name="sqliDataDAO" ref="sqliDataDAOhibernate"/>
        <!--
        <property name="sqliDataDAO" ref="sqliDataDAOjdbc" />
        <property name="sqliDataDAO" ref="sqliDataDAOhibernate" />
        -->


        <property name="xssDataDAO" ref="xssDataDAO"/>

    </bean>


</beans>

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean id="sessionFactory"
          class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="jdbcDataSource"/>
        <property name="mappingDirectoryLocations">
            <value>classpath:/com/webbilly/dao/hibernate/hbm</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                <prop key="hibernate.dialect">${database.dialect}</prop>
            </props>
        </property>
    </bean>

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

    <bean id="genericDAO" class="com.webbilly.dao.hibernate.GenericDAO"
          abstract="true">
        <property name="hibernateTemplate" ref="hibernateTemplate"/>
    </bean>

    <bean id="sqliDataDAOhibernate" parent="genericDAO">
        <constructor-arg>
            <value>com.webbilly.domain.SQLiData</value>
        </constructor-arg>
    </bean>
    <bean id="xssDataDAO" parent="genericDAO">
        <constructor-arg>
            <value>com.webbilly.domain.XssData</value>
        </constructor-arg>
    </bean>

    <bean id="sqliDataDAOjdbc" class="com.webbilly.dao.jdbc.SQLiDAO">
        <property name="dataSource" ref="jdbcDataSource"/>
    </bean>

    <bean id="jdbcDataSource"
          class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${database.driver}"/>
        <property name="url" value="${database.url}"/>
        <property name="username" value="${database.username}"/>
        <property name="password" value="${database.password}"/>
        <property name="connectionProperties">
            <props>
                <prop key="allowMultiQueries">true</prop>
            </props>
        </property>
    </bean>

</beans>

我的数据对象(这些是否有名称?总是将它们称为域对象,但我不确定这是否被广泛接受的术语)。

package com.webbilly.domain;

/**
 * Created by christopher on 12/12/14.
 */
public class XssData {

    private int id;
    private String userName;
    private String message;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}


package com.webbilly.domain;

/**
 * Created by christopher on 12/3/14.
 */
public class SQLiData {

    private String id;
    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

持久层

package com.webbilly.dao;

import java.util.Collection;

public interface IGenericDAO<T> {
    void save(T t);

    Collection<T> getAll();

    T getById(int id);

    void delete(int id);
}

package com.webbilly.dao.hibernate;

import com.webbilly.dao.IGenericDAO;
import org.springframework.orm.hibernate4.support.HibernateDaoSupport;

import java.util.Collection;

public class GenericDAO<T> extends HibernateDaoSupport implements IGenericDAO<T> {

    /**
     * ******************************************************
     * ********* Accessors and private members ****************
     * *******************************************************
     */

    private Class<T> type;

    public GenericDAO(Class<T> type) {
        this.type = type;
    }

    public T getById(int id) {
        return (T) getHibernateTemplate().get(type, id);
    }

    public Collection<T> getAll() {
        return getHibernateTemplate().loadAll(type);
    }

    public void save(T t) {
        getHibernateTemplate().saveOrUpdate(t);
    }

    public void delete(int id) {
        getHibernateTemplate().delete(getById(id));
    }

}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.webbilly.domain">
    <class name="SQLiData" table="sqli">
        <id column="id" name="id" type="int">
            <generator class="increment"/>
        </id>
        <property name="value" type="string">
            <column name="value"/>
        </property>
    </class>
</hibernate-mapping>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.webbilly.domain">
    <class name="XssData" table="xss">
        <id column="id" name="id" type="int">
            <generator class="increment"/>
        </id>
        <property name="userName" type="string">
            <column name="user_name"/>
        </property>
        <property name="message" type="string">
            <column name="message"/>
        </property>
    </class>
</hibernate-mapping>

服务层(它实际上只是一个类;我的应用程序还不是那么大)。

package com.webbilly.service;

import com.webbilly.dao.IGenericDAO;
import com.webbilly.domain.SQLiData;
import com.webbilly.domain.XssData;

import java.util.Collection;

/**
 * Created by christopher on 12/3/14.
 */
public class SQLiServices {


    private IGenericDAO<SQLiData> sqliDataDAO;
    private IGenericDAO<XssData> xssDataDAO;

    public void sqlInject(String str) {
        SQLiData sqliData = new SQLiData();
        sqliData.setValue(str);
        getSqliDataDAO().save(sqliData);
    }

    public void xssSave(XssData data) {
        xssDataDAO.save(data);
    }

    public Collection<XssData> getAllPosts() {
        return xssDataDAO.getAll();
    }

    public IGenericDAO<SQLiData> getSqliDataDAO() {
        return sqliDataDAO;
    }

    public void setSqliDataDAO(IGenericDAO<SQLiData> sqliDataDAO) {
        this.sqliDataDAO = sqliDataDAO;
    }

    public IGenericDAO<XssData> getXssDataDAO() {
        return xssDataDAO;
    }

    public void setXssDataDAO(IGenericDAO<XssData> xssDataDAO) {
        this.xssDataDAO = xssDataDAO;
    }
}

1 个答案:

答案 0 :(得分:0)

HibernateTemplate不管理事务,而是需要HibernateTransactionManager

写操作需要在事务的上下文中执行,因此您还需要使用@Transactional注释DAO或您的服务。