Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript spring mvc hibernate restful(并发)问题_Javascript_Multithreading_Spring_Hibernate_Spring Mvc - Fatal编程技术网

Javascript spring mvc hibernate restful(并发)问题

Javascript spring mvc hibernate restful(并发)问题,javascript,multithreading,spring,hibernate,spring-mvc,Javascript,Multithreading,Spring,Hibernate,Spring Mvc,最近,我在web应用程序中遇到了一个问题。我将spring mvc restful应用程序与hibernate一起作为jpa使用 客户端可以使用以下格式构建xml文件: <SCCF> <registerSCCF>...</registerSCCF> ... <registerSCCF>...</registerSCCF> </SCCF> 如果我将所有setter设置为静态值,如: cns.setCo

最近,我在web应用程序中遇到了一个问题。我将spring mvc restful应用程序与hibernate一起作为jpa使用

客户端可以使用以下格式构建xml文件:

<SCCF>
    <registerSCCF>...</registerSCCF>
    ...
    <registerSCCF>...</registerSCCF>
</SCCF>
如果我将所有setter设置为静态值,如:

cns.setContact_email("test@test.test");
如果不使用参数中的值,那么应用程序可以很好地运行多线程测试

存在控制器调用服务方法的错误:

@RequestMapping(value = "/test",method=RequestMethod.POST)
public @ResponseBody SCCFResponseList getPostResults(@RequestBody SCCFVOList sccf){
    ...
    for(SCCFVO sccfvo : sccf.getSCCFVOList()){
        ...
        boolean result = sccfservice.postSCCFService(sccfvo);
        ...
    }
    ...
}

public class SCCFVOList {
下面是请求主体类:

@XmlElement(name="registerSCCF")
public class SCCFVOList {
private Vector<SCCFVO> SCCFVOList = null;

public Vector<SCCFVO> getSCCFVOList(){
    return SCCFVOList;
}

public void setSCCFVOList(Vector<SCCFVO> SCCFVOList){
    this.SCCFVOList = SCCFVOList;
}

}
@xmlement(name=“registerSCCF”)
公共类SCCFVOList{
私有向量SCCFVOList=null;
公共向量getSCCFVOList(){
返回SCCFVOList;
}
公共无效设置CCFvolist(向量SCCFVOList){
this.SCCFVOList=SCCFVOList;
}
}
这是刀

public class CNSDao extends GenericHibernateDAO<CustomersNoneSSO, Long> {}

public abstract class GenericHibernateDAO<T, ID extends Serializable>
    implements GenericDAO<T, ID> {

private Class<T> persistentClass;
private Session session;

SessionFactory sessionFactory;

public void setSessionFactory(SessionFactory sessionFactory){
    this.sessionFactory = sessionFactory;
}

public GenericHibernateDAO() {
    this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
            .getGenericSuperclass()).getActualTypeArguments()[0];
}

@SuppressWarnings("unchecked")
public void setSession(Session s) {
    this.session = s;
}

protected Session getSession() {
    session = sessionFactory.getCurrentSession();
    if (session == null)
        throw new IllegalStateException(
                "Session has not been set on DAO before usage");
    return session;
}

public Class<T> getPersistentClass() {
    return persistentClass;
}

@SuppressWarnings("unchecked")
public T makePersistent(T entity) {
    getSession().saveOrUpdate(entity);
    return entity;
}

public void makeTransient(T entity) {
    getSession().delete(entity);
}

...
}
public类CNSDao扩展了generichbernatedao{}
公共抽象类generichBernateDao
实现GenericDAO{
私有类persistentClass;
非公开会议;
会话工厂会话工厂;
public void setSessionFactory(SessionFactory SessionFactory){
this.sessionFactory=sessionFactory;
}
公共genericibernatedao(){
this.persistentClass=(Class)((ParameteredType)getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
@抑制警告(“未选中”)
公开作废设置会话(会话s){
this.session=s;
}
受保护会话getSession(){
session=sessionFactory.getCurrentSession();
if(会话==null)
抛出新的非法状态异常(
“使用前未在DAO上设置会话”);
返回会议;
}
公共类getPersistentClass(){
返回persistentClass;
}
@抑制警告(“未选中”)
公共T使持久化(T实体){
getSession().saveOrUpdate(实体);
返回实体;
}
公共无效(T实体){
getSession().delete(实体);
}
...
}
控制器方法或服务方法应该有问题。还是不知道出了什么问题。

你的刀有缺陷

你的刀是单刀,只有一把。Hibernate
会话
对象不是线程安全的,不应跨线程使用

您有1个dao,2个线程,线程1获取会话的实例X1,线程2将其重置为实例X2,现在它们突然共享同一个会话,更不用说线程1甚至可能在2个不同的会话上运行

正如我在注释中提到的,从不将
会话
存储在实例变量中。移除它

public abstract class GenericHibernateDAO<T, ID extends Serializable> implements GenericDAO<T, ID> {

    private Class<T> persistentClass;

    private SessionFactory sessionFactory;

    public GenericHibernateDAO() {
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    public void setSessionFactory(SessionFactory sessionFactory){
        this.sessionFactory = sessionFactory;
    }


    protected Session getSession() {
        return sessionFactory.getCurrentSession();
    }
公共抽象类genericBernateDao实现GenericDAO{
私有类persistentClass;
私人会话工厂会话工厂;
公共genericibernatedao(){
this.persistentClass=(Class)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public void setSessionFactory(SessionFactory SessionFactory){
this.sessionFactory=sessionFactory;
}
受保护会话getSession(){
返回sessionFactory.getCurrentSession();
}

另外,我建议删除这个,而改用use,这样可以省去创建和维护自己的泛型dao的麻烦。(您提到您使用JPA,如果对实体进行了注释,那么应该很容易做到).

首先,我希望服务保存所有内容或不保存所有内容,我不会在控制器中循环,但这就是我。看起来您的dao中存在问题,请发布代码。循环应该在控制器中进行,这是一个很好的观点。但它们确实都保存在数据库中,只有少数在执行时保存。我将发布dao an是的。这就是你的问题…永远不要(我提到过永远不要)将会话存储在一个成员变量中…会话
不是线程安全的,你有一个dao实例,现在想象一下多个线程会发生什么…删除存储(和setter!),并始终使用
sessionFactory.getCurrentSession()
。我有点惊讶,因为我在这里使用了泛型dao模式,不知何故,我将会话变量的private改为protected。将其设置为back后,仍然得到相同的异常:(你的意思是我应该在CNSDao类中使用会话吗?正如我提到的,永远不要使用实例变量来存储会话!删除属性,删除setter,getter应该只是调用
sessionFactory.getCurrentSession()
。如果100个线程都试图在dao的一个实例上设置和使用一个会话,你会怎么办?这只有在dao不是单实例的情况下才有效。你太棒了。我刚刚按照你的建议编辑了getSession()方法。它很完美!我稍后会深入研究Spring数据JPA。哈哈
public abstract class GenericHibernateDAO<T, ID extends Serializable> implements GenericDAO<T, ID> {

    private Class<T> persistentClass;

    private SessionFactory sessionFactory;

    public GenericHibernateDAO() {
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    public void setSessionFactory(SessionFactory sessionFactory){
        this.sessionFactory = sessionFactory;
    }


    protected Session getSession() {
        return sessionFactory.getCurrentSession();
    }