Hibernate更新问题 - OpenSessionInViewFilter [英] Hibernate Update Problems - OpenSessionInViewFilter

查看:120
本文介绍了Hibernate更新问题 - OpenSessionInViewFilter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我已经经历了大概5个小时,试图通过使用Spring MVC 3和OpenSessionInViewFilter的应用程序中的休眠来更新对象。可以在StackOverflow和其他论坛中使用的线程!



Hibernate不会抛出任何错误,并且说对象已更新,但它不反映在我的数据库中。 p>

任何帮助都将得到大量赞赏。

因此,这是我的 JSON请求

  {
id:14,
name:无论,
contactNumber:918026754027,
manager:Vishwas, - >我已更新此值
capacity:222,
addressId:31,
streetAddress:1168,1st Block,17th Main,ABC,
countryId:1,
stateId:1,
cityId:1,
area:DEF,
pincode:560050
}

控制器: strong>

  @RequestMapping(value =/ branches / update,method = RequestMethod.POST,headers = {Content- Type = application / json})
@ResponseBody
public Map< String,Object> updateBranch(@RequestBody Map< String,String> requestMap){
布尔状态= false;
布尔branchStatus = false;
地图< String,Object> statusMap = new HashMap< String,Object>();
Branch branch = new Branch();

地址=新地址();
address.setId(Long.parseLong(requestMap.get(addressId)));
address.setCountry(countryService.getCountryById(Long.parseLong(requestMap.get(countryId))));
address.setState(stateService.getStateById(Long.parseLong(requestMap.get(stateId))));
address.setCity(cityService.getCityById(Long.parseLong(requestMap.get(cityId))));
address.setType(BRANCH);
address.setArea(requestMap.get(area));
address.setStreetAddress(requestMap.get(streetAddress));
address.setPincode(requestMap.get(pincode));
address.setModifiedBy(vishwas);
address.setModifiedTimestamp(new Date());

status = addressService.updateAddress(address);

if(status){
branch.setId(Long.parseLong(requestMap.get(id)));
branch.setName(requestMap.get(name));
branch.setAddress(address);
branch.setContactNumber(requestMap.get(contactNumber));
branch.setManager(requestMap.get(manager));
branch.setActive(true);
branch.setCapacity(Integer.parseInt(requestMap.get(capacity)));
branch.setModifiedTimestamp(new Date());
branch.setModifiedBy(vishwas);
branchStatus = branchService.updateBranch(branch);
}

if(branchStatus){
statusMap.put(status,branchStatus);
statusMap.put(message,Branch was successfully successfully);
} else {
boolean delStatus = addressService.deleteAddress(address);
statusMap.put(status,branchStatus);
statusMap.put(message,问题更新分支,请与您的系统管理员联系);
}
返回statusMap;
}

服务等级:

  @Service(branchService)
@Transactional
公共类BranchServiceImpl实现BranchService {

@ Autowired
private BranchDAO branchDAO;
private static Logger logger = Logger.getLogger(BranchService.class.getName());

public boolean updateBranch(Branch branch){
logger.debug(处理请求到dao来更新分支 - >+ branch.getId());
返回branchDAO.updateBranch(分支);


DAO方法:

  public boolean updateBranch(Branch branch){
boolean status = false;
尝试{
logger.debug(尝试更新分支 - >+ branch.getId());
sessionFactory.getCurrentSession()。update(branch);
status = true;
} catch(HibernateException异常){
logger.error(Problem updating an branch - >+ exception.getMessage());
} catch(Exception exception){
logger.error(更新分支的问题 - >+ exception.getMessage());
}
返回状态;
}

**更新2:根据Mr.Deinum的建议,事务管理器配置到o2-data.xml,并且现在只扫描调度程序中的控制器,同时扫描o2-data.xml中的其他组件



strong>

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

xsi:schemaLocation =http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http:// www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx http:/ /www.springframework.org/schema/tx/spring-tx-3.2.xsd
>
< context:component-scan base-package =com.adwitiya.o2plus>
< context:exclude-filter type =annotationexpression =org.springframework.stereotype.Controller/>
< / context:component-scan>

< bean id =myDataSourceclass =org.apache.commons.dbcp.BasicDataSourcedestroy-method =close>
< property name =driverClassNamevalue =$ {database.driverClass}/>
< property name =urlvalue =$ {database.url}/>
< property name =usernamevalue =$ {database.username}/>
< property name =passwordvalue =$ {database.password}/>
< / bean>

<! - Hibernate Session Factory - >
< bean id =mySessionFactoryclass =org.springframework.orm.hibernate4.LocalSessionFactoryBean>
< property name =dataSourceref =myDataSource/>
< property name =packagesToScan>
< array>
<值> com.adwitiya.o2plus.model< /值>
< / array>
< / property>
< property name =hibernateProperties>
<值>
hibernate.dialect = org.hibernate.dialect.MySQLDialect
hibernate.show_sql = true
< / value>
< / property>
< / bean>

<! - Hibernate Transaction Manager - >
< bean id =transactionManagerclass =org.springframework.orm.hibernate4.HibernateTransactionManager>
< property name =sessionFactoryref =mySessionFactory/>
< / bean>

<! - 激活基于注释的交易管理 - >
< tx:注解驱动的事务管理器=transactionManager/>


< / beans>

分派器配置:

 <?xml version =1.0encoding =UTF-8?> 
< beans xmlns:xsi =http://www.w3.org/2001/XMLSchema-instance
xmlns:context =http://www.springframework.org/schema/context
xmlns:mvc =http://www.springframework.org/schema/mvc
xmlns =http://www.springframework.org/schema/beans
xsi :schemaLocation =http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework。 org / schema / context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework .ORG /模式/ MVC /弹簧-MVC-3.2.xsd>

< context:component-scan base-package =com.adwitiya.o2plus>
< context:include-filter type =annotationexpression =org.springframework.stereotype.Controller/>
< / context:component-scan>

< mvc:注释驱动>
< mvc:message-converters>
<! - 使用HibernateAware映射器而不是默认值 - >
< bean class =org.springframework.http.converter.json.MappingJackson2HttpMessageConverter>
< property name =objectMapper>
< bean class =com.adwitiya.o2plus.utilities.HibernateAwareObjectMapper/>
< / property>
< / bean>
< / mvc:message-converters>
< / mvc:注释驱动>

< bean id =viewResolver
class =org.springframework.web.servlet.view.InternalResourceViewResolver>
< property name =prefixvalue =/ WEB-INF / pages //>
< property name =suffixvalue =。jsp/>
< / bean>

< mvc:resources mapping =/ gui / **location =/ gui //>

< bean class =org.springframework.beans.factory.config.PropertyPlaceholderConfigurer>
< property name =locations>
< list>
< value> classpath:application.properties< / value>
< / list>
< / property>
< / bean>

< / beans>

web.xml

 <?xml version =1.0encoding =UTF-8?> 
< web-app xmlns:xsi =http://www.w3.org/2001/XMLSchema-instance
xmlns =http://java.sun.com/xml/ns / javaee
xsi:schemaLocation =http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd
version =3.0>

< display-name> O2 Plus< / display-name>

< context-param>
< param-name> contextConfigLocation< / param-name>
< param-value>
/WEB-INF/spring/o2-data.xml
/WEB-INF/spring/o2-utils.xml
/WEB-INF/spring/o2-security.xml
< /参数值>
< / context-param>

< listener>
< listener-class> org.springframework.web.context.ContextLoaderListener< / listener-class>
< / listener>

< filter>
< filter-name> springSecurityFilterChain< / filter-name>
< filter-class> org.springframework.web.filter.DelegatingFilterProxy< / filter-class>
< / filter>
< filter-mapping>
< filter-name> springSecurityFilterChain< / filter-name>
< url-pattern> / *< / url-pattern>
< / filter-mapping>

< filter>
< filter-name> hibernateFilter< / filter-name>
< filter-class> org.springframework.orm.hibernate4.support.OpenSessionInViewFilter< / filter-class>
< init-param>
< param-name> sessionFactoryBeanName< / param-name>
< param-value> mySessionFactory< / param-value>
< / init-param>
< / filter>

< filter-mapping>
< filter-name> hibernateFilter< / filter-name>
< url-pattern> / *< / url-pattern>
< dispatcher> REQUEST< / dispatcher>
< dispatcher> FORWARD< / dispatcher>
< / filter-mapping>

< servlet>
< servlet-name> o2-dispatcher< / servlet-name>
< servlet-class> org.springframework.web.servlet.DispatcherServlet< / servlet-class>
< init-param>
< param-name> contextConfigLocation< / param-name>
< param-value> /WEB-INF/spring/o2-dispatcher-servlet.xml< / param-value>
< / init-param>
< / servlet>

< servlet-mapping>
< servlet-name> o2-dispatcher< / servlet-name>
< url-pattern> /< / url-pattern>
< / servlet-mapping>

< / web-app>


解决方案

 < context:component-scan base-package =com.adwitiya.o2plus/> 

< context:component-scan ... /> 位于由 DispatcherServlet 加载的配置中。

 < tx:annotation-driven transaction-manager =transactionManager/> 

< tx:annotation-driven /> 位于由 ContextLoaderLIstener 加载的配置中。



A Bean(Factory)PostProcessor 只对与其加载的相同的 ApplicationContext 中的bean进行操作。儿童情况。 < tx:annotation-driven /> 注册由 InfrastructureAdvisorAutoProxyCreator 处理的拦截器(或方面)这是一个 BeanPostProcessor



解决方案



< tx:annotation-driven /> 移动到 DispatcherServlet 的配置中,或者修改组件扫描。 ContextLoaderListener 应扫描除 @Controller 注释bean以外的任何内容,而 DispatcherServlet 应该只扫描 @Controller 带注释的bean。



ContextLoaderListener code> configuration。

 < context:component-scan base-package =com.adwitiya.o2plus> ; 
< context:exclude-filter type =annotationexpression =org.springframework.stereotype.Controller/>
< / context:component-scan>

DispatcherServlet 配置

 < context:component-scan base-package =com.adwitiya.o2plususe-default-filters =false> 
< context:include-filter type =annotationexpression =org.springframework.stereotype.Controller/>
< / context:component-scan>


It's been about 5 hours trying to update an object through hibernate in my application using Spring MVC 3 and OpenSessionInViewFilter without any luck.

I've possibly gone through all the threads available in StackOverflow and other forums!

Hibernate doesn't throw any error, and says the object was updated but it doesn't reflect in my DB.

Any help would be massively appreciated.

So, here's my JSON request to update:

{
    "id": "14",
    "name": "Whatever",
    "contactNumber": "918026754027",
    "manager": "Vishwas", --> I've updated this value
    "capacity": "222",
    "addressId": "31",
    "streetAddress": "1168, 1st Block, 17th Main, ABC",
    "countryId": "1",
    "stateId": "1",
    "cityId": "1",
    "area": "DEF",
    "pincode": "560050"
}

Controller:

@RequestMapping(value = "/branches/update", method = RequestMethod.POST, headers = {"Content-Type=application/json"})
    @ResponseBody
    public Map<String, Object> updateBranch(@RequestBody Map<String, String> requestMap) {
        boolean status = false;
        boolean branchStatus = false;
        Map<String, Object> statusMap = new HashMap<String, Object>();
        Branch branch = new Branch();

        Address address = new Address();
        address.setId(Long.parseLong(requestMap.get("addressId")));        
        address.setCountry(countryService.getCountryById(Long.parseLong(requestMap.get("countryId"))));
        address.setState(stateService.getStateById(Long.parseLong(requestMap.get("stateId"))));
        address.setCity(cityService.getCityById(Long.parseLong(requestMap.get("cityId"))));
        address.setType("BRANCH");
        address.setArea(requestMap.get("area"));
        address.setStreetAddress(requestMap.get("streetAddress"));
        address.setPincode(requestMap.get("pincode"));
        address.setModifiedBy("vishwas");
        address.setModifiedTimestamp(new Date());

        status = addressService.updateAddress(address);

        if (status) {
            branch.setId(Long.parseLong(requestMap.get("id")));
            branch.setName(requestMap.get("name"));
            branch.setAddress(address);
            branch.setContactNumber(requestMap.get("contactNumber"));
            branch.setManager(requestMap.get("manager"));
            branch.setActive(true);
            branch.setCapacity(Integer.parseInt(requestMap.get("capacity")));
            branch.setModifiedTimestamp(new Date());
            branch.setModifiedBy("vishwas");            
            branchStatus = branchService.updateBranch(branch);
        }

        if (branchStatus) {
            statusMap.put("status", branchStatus);
            statusMap.put("message", "Branch was updated successfully");
        } else {
            boolean delStatus = addressService.deleteAddress(address);
            statusMap.put("status", branchStatus);
            statusMap.put("message", "Problem updating branch. Please check with your system administrator");
        }
        return statusMap;
    }

Service class:

@Service("branchService")
@Transactional
public class BranchServiceImpl implements BranchService {

    @Autowired
    private BranchDAO branchDAO;
    private static Logger logger = Logger.getLogger(BranchService.class.getName());

    public boolean updateBranch(Branch branch) {
        logger.debug("Processing request to dao to update a branch --> " + branch.getId());
        return branchDAO.updateBranch(branch);
    }
}

DAO method:

public boolean updateBranch(Branch branch) {
        boolean status = false;
        try {
            logger.debug("Trying to update a branch --> " + branch.getId());                            
            sessionFactory.getCurrentSession().update(branch);            
            status = true;
        } catch (HibernateException exception) {
            logger.error("Problem updating a branch --> " + exception.getMessage());
        } catch (Exception exception) {
            logger.error("Problem updating a branch --> " + exception.getMessage());
        }
        return status;
    }

**Update 2: As suggested by Mr.Deinum, I've moved transaction manager config to o2-data.xml and now scanning only the controllers in the dispatcher while scanning other components in o2-data.xml

Data Configuration

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

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
">
    <context:component-scan base-package="com.adwitiya.o2plus">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${database.driverClass}"/>
        <property name="url" value="${database.url}"/>
        <property name="username" value="${database.username}"/>
        <property name="password" value="${database.password}"/>
    </bean>

    <!-- Hibernate Session Factory -->
    <bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource"/>
        <property name="packagesToScan">
            <array>
                <value>com.adwitiya.o2plus.model</value>
            </array>
        </property>
        <property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.MySQLDialect
                hibernate.show_sql=true
            </value>
        </property>
    </bean>

    <!-- Hibernate Transaction Manager -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>

    <!-- Activates annotation based transaction management -->
    <tx:annotation-driven transaction-manager="transactionManager"/>


</beans>

Dispatcher Configuration:

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

    <context:component-scan base-package="com.adwitiya.o2plus">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <mvc:annotation-driven>
        <mvc:message-converters>
            <!-- Use the HibernateAware mapper instead of the default -->
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="com.adwitiya.o2plus.utilities.HibernateAwareObjectMapper"/>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

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

    <mvc:resources mapping="/gui/**" location="/gui/"/>

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:application.properties</value>
            </list>
        </property>
    </bean>

</beans>

web.xml

 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

    <display-name>O2 Plus</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/o2-data.xml
            /WEB-INF/spring/o2-utils.xml
            /WEB-INF/spring/o2-security.xml
        </param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>hibernateFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
        <init-param>
            <param-name>sessionFactoryBeanName</param-name>
            <param-value>mySessionFactory</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>hibernateFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

    <servlet>
        <servlet-name>o2-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/o2-dispatcher-servlet.xml</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>o2-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

解决方案

<context:component-scan base-package="com.adwitiya.o2plus" />

This <context:component-scan ... /> is located the configuration that is loaded by the DispatcherServlet.

<tx:annotation-driven transaction-manager="transactionManager"/>

The <tx:annotation-driven /> is located in the configuration that is loaded by the ContextLoaderLIstener.

A Bean(Factory)PostProcessor only operates on beans in the same ApplicationContext that it is loaded in. It doesn't do anything for beans in parent or child contexts. The <tx:annotation-driven /> registers an interceptor (or aspect) which is processed by an InfrastructureAdvisorAutoProxyCreator which is a BeanPostProcessor.

Solution

Either move your <tx:annotation-driven /> to your configuration of the DispatcherServlet or modify your component scan. The ContextLoaderListener should scan for anything but @Controller annotated beans, whereas the DispatcherServlet should scan only for @Controller annotated beans.

ContextLoaderListener configuration.

<context:component-scan base-package="com.adwitiya.o2plus">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> 
</context:component-scan>

DispatcherServlet configuration

<context:component-scan base-package="com.adwitiya.o2plus" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> 
</context:component-scan>

这篇关于Hibernate更新问题 - OpenSessionInViewFilter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆