public class CatAction {
private ICatService catService;
public ICatService getCatService() {
return catService;
}
public void setCatService(ICatService catService) {
this.catService = catService;
} private List<Cat> catlist = new ArrayList<Cat>();
private Cat   cat;
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
} public String getMotherId() {
return motherId;
}
public void setMotherId(String motherId) {
this.motherId = motherId;
}
// private Cat  catMother = new Cat();
public List<Cat> getCatlist() {

return catlist;
}
public void setCatlist(List<Cat> catlist) {
this.catlist = catlist;
}


public String list()throws Exception
{
catlist = catService.listCats();
return "list";
}

public String add()throws Exception 
{
catService.createCat(cat);       return list();
}

}配置如下:
<bean id="catAction"  class="com.struts2.bean.hibernate.CatAction" scope="prototype">
<property name="catService" ref="catService">
</property>
</bean>
org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.struts2.bean.hibernate.Cat; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.struts2.bean.hibernate.Cat
org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:655)
org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:413)
org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:370)
org.springframework.orm.hibernate3.HibernateTemplate.persist(HibernateTemplate.java:719)
com.struts2.bean.hibernate.CatDaoImpl.createCat(CatDaoImpl.java:12)
com.struts2.bean.hibernate.CatServiceImpl.createCat(CatServiceImpl.java:21)请高手指点一下可能是什么原因

解决方案 »

  1.   

    感觉应该是action中的cat的值保留了上一次的。不知道为什么。请高手指点一下,最好给一些详细的实例代码。
      

  2.   

    1. 应该不是保留上一次的。。估计是你第二次的id号为空了。。debug看一下参数。每次改变id号。。且不能为空。。
    2. 还有一种原因是关联关系配置时,set标签的级联方式尽量使用cascade=CascadeType.REFRESH 
      

  3.   

    每一次都是新建一个对象,所以id为空是正常的。现在奇怪的是,
    我第一进入到新规的jsp界面,输入项都为空,添加一条记录成功。
    但是第二次在进入到新规的jsp界面,输入项都是上次输入的值,这个地方就不太正常了(应该为空),
    而且提交的时候,cat里面也保留了上一次提交的id(正常不应该有id,应该是数据库自动生成的),所以就错了。
      

  4.   

    很明显没有清除缓存。。你这种情况在hibernate中连续插入时,每次插入后需要flush一下看看我之前回的一个帖子:
    http://topic.csdn.net/u/20111126/09/adabdc00-ee42-4446-9eef-6f51be937f3d.html
      

  5.   

    struts2配置文件的代码我看看吧.
      

  6.   

    <!DOCTYPE struts PUBLIC
              "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
              "http://struts.apache.org/dtds/struts-2.0.dtd">
              
    <struts>
        
        <constant name="struts.objectFactory" value="org.apache.struts2.spring.StrutsSpringObjectFactory" />
        <package name="main" namespace="/" extends="struts-default">
            <global-results>
            <result name="login">/login.jsp</result>
            </global-results>
                   
                           
             <action name="*Cat" class="catAction"  method="{1}" >
            <result >/successCat.jsp</result>
            <result name="list">/listCat.jsp</result>
            <result name="add">/editCat.jsp</result>
            <result name="initadd">/editCat.jsp</result>
            <result name="edit">/editCat.jsp</result>
            </action>
           
        </package>
        
    </struts>
      

  7.   

    这一句应该是你添加的返回代码吧:<result name="add">/editCat.jsp</result>改为:<result name="add" type="redirect">/editCat.jsp</result>应该就可以了。
      

  8.   


    何必加一个type="redirect" 请问意义何在 没有的话一样跳转 我记得redirect是重定位到另外一个action吧,既然是跳到jsp就不需要用了
      

  9.   

    已经说的很清楚了 第一次构造出的实例会一直使用,不管你请求多少次都是这个实例(action)在处理
      

  10.   

    我设了一个断点,发现action只创建了一次。
    没有人遇到同样的问题吗?
      

  11.   

    /editCat.jsp这个页面的代码看看
      

  12.   

    <%@ page contentType="text/html; charset=utf-8" language="java" import="java.util.ArrayList"
    import="java.util.List"  errorPage="" %>
    <%@ taglib uri="/struts-tags" prefix="struts"  %>
     <%@ taglib prefix="sx" uri="/struts-dojo-tags"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>My jsp 'index.jsp' starting page</title>
    <link href="css/FormUITag.css" rel="stylesheet" type="text/css" />
    <sx:head/>
    </head>
    <body>
    <struts:form  action="addCat!add" namespace="/" >
    <struts:label value="form标签"></struts:label>
    <struts:textfield name="cat.name" label="Name:" />
    <struts:select label="Mother"
           name="motherId"
           list="mapMM"
           listKey="key"
           listValue="value"
           headerKey="0" headerValue="--请选择子类型--"
    /><struts:textfield  name="cat.description" label="Description:" />
    <struts:submit value="添加、编辑人员"></struts:submit>
    <struts:hidden name="command" id="comand"/>
    <struts:hidden name="editId" id="editId"/>
    </struts:form> 
    </body>
    </html>
      

  13.   

    <result name="add">/editCat.jsp</result>
      <result name="initadd">/editCat.jsp</result>
      <result name="edit">/editCat.jsp</result>你先把这三个result都加上type="redirect",重新部署项目重新启动项目,我估计原因就是你所有请求都是用的转发,这样原先实体类的值都会保存在ValueStack中,而你页面中刚好又使用的是struts标签,就算你没有写value它也会自动从ValueStack中取出name与之相对应的值赋上,当你下此再增加是就会主键重复。一般情况下,增删改操作都需要type="redirect"就是重定向,避免重复提交,只有查询时才会使用转发。如果还是不行你可以试着将struts标签先换为普通标签试试。
      

  14.   

    不行。我觉得问题应该在,为什么我设置了scope="prototype" ,但是action还是只创建了一次。我跟了,action就只创建了一次。
      

  15.   

    这样吧,你把项目发我邮箱来[email protected],我一会闲了帮你看看。
      

  16.   

    struts2本身就是每次重新创建一个action,你把你那个scope去掉试试