当ID为AUTO INCREMENT时,无法克隆Model.Object

时间:2016-12-12 20:53:19

标签: java playframework clone ebean

我实现了可克隆的接口来克隆我的对象(复制按钮1或多个Object),但是,当模型的Id是自动递增时,object.save();不起作用! 我在网上尝试了很多解决方案,但没办法!

1-在我的模特中:

@Override
public Computer clone()
{

    try
    {
        Computer nouveau = (Computer) super.clone();
        return nouveau;
    }

    catch (CloneNotSupportedException e)
    {
        e.printStackTrace();
        throw new RuntimeException();
    }
}

控制器:

public Result CopyComputers(Long selected)
{
        Computer c = Computer.find.byId(selected);
        Computer cClone = c.clone();
        Logger.debug("Object is perfectly copied and ID TOO !!!! : "+cClone);
        cClone.save(); // never works coz id is the one from primary model object.

}

我试过这些解决方案,但没有一个正在运行! 1-将id设置为NULL以保存... 2-代型如下图所示

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(columnDefinition = "serial")
    public Long id;

任何人都有想法吗?因为如果我的对象有许多或其他列的onoomany .....我每次都不能这样做:

public Result CopyComputers(String selected)
{



        //Computer cClone = c.clone();

  String[] ids = selected.split(";");

  for (String temp : ids)
  {
        Computer c = Computer.find.byId(Long.parseLong(temp));
        try
        {

            Computer n = new Computer();
            if (c != null)
            {
            n.name = c.name;
            n.status = c.status;            
            n.introduced = c.introduced;
            n.discontinued = c.discontinued;
            n.createdt = c.createdt;
            n.createby = c.createby;
            n.moddt = c.moddt;
            n.modby = c.modby;
            n.site = c.site;
            n.company = c.company;

            n.save();
            Logger.debug("zzzzzzzz : "+n.id   +" "+c.id);
            }
            //cClone.save();

        }

        catch (Exception e)
        {
            Logger.error("Clone error", e);

        }



   Logger.info("Computer Object "+temp+" has been Copied");

   } // end for

        return GO_HOME;

}  

2 个答案:

答案 0 :(得分:2)

您不需要(也不应该)在Ebean实体bean上使用克隆。相反,您可以将id值设置为null并使用显式insert(),如:

Computer c = Computer.find.byId(selected);
// null out the current id value if you are
// inserting back into the same db
c.setId(null); 

// use explicit insert. This tells Ebean to ignore the 
// state of the entity and forces a sql insert
c.insert(); 

请注意,您也可以使用BeanState.resetForInsert(),当插入/保存级联到您也希望复制的关联bean时,可以执行此操作。

也就是说,在调用insert()之前(将级联到关联的bean),我们应该修改那些相关/关联bean,将其id值设置为null并调用Ebean.getBeanState(otherBean).resetForInsert() ...因此这些其他相关豆也被插入。

答案 1 :(得分:0)

是的,clone会创建对象的副本,包括所有属性,但是如上所述at the Java docs

  

按照惯例,此方法返回的对象应独立于此对象(正在克隆)。为了实现这种独立性,可能需要在返回之前修改super.clone返回的对象的一个​​或多个字段

您的save失败了,因为持久性机制正在尝试使用现有的INSERT执行id,然后您会遇到约束错误。要解决这个问题,请执行以下操作:

@Override
public Computer clone() {

    try {
        Computer nouveau = (Computer) super.clone();
        nouveau.id = null; // reseting the id
        return nouveau;
    }

    catch (CloneNotSupportedException e) {
        e.printStackTrace();
        throw new RuntimeException();
    }
}

请注意restrictions and conventions defined by clone method