更新替换的OneToMany ArrayList实体的级联对象

时间:2013-12-24 13:50:34

标签: playframework ebean

我正在使用PlayFramework 2.2.1 / Java / Ebean / MySQL
Thera是两个类(实体):

@Entity
public class Cart extends Model{
    @Id @GeneratedValue
    public int id;
    @OneToMany(cascade=CascadeType.ALL)
    public List <Item> items = new ArrayList<>();
}

@Entity
public class Item extends Model{
    @Id @GeneratedValue
    public int id;
    public String name;
}

我正在尝试使用对Cart对象的ArrayList中的Item对象所做的更改来更新DB表中的现有记录 问题 - 如果我在项目ArrayList中替换对象,Ebean不会更新,但会在表格中添加新记录,但如果我更改字段值,它会更新现有记录项目对象直接:

    Cart cart = new Cart();
    Item item1 = new Item(); item1.name = "Banana";
    Item item2 = new Item(); item2.name = "Peach";
    cart.items = new ArrayList<Item>();
    cart.items.add(item1);
    cart.items.add(item2);
    cart.save();

保存没有问题,但是当我尝试阅读和更新时:

    Cart cart = Cart.find.all().get(0);
    cart.items.get(0).name="Orange";                //updates perfectly
    Item item3 = new Item(); item3.name = "Apple";  
    cart.items.set(1, item3);                       //adds additional third record
    cart.update();

我做错了什么?

2 个答案:

答案 0 :(得分:0)

你做的一切都是正确的。 如果要更新某些内容,则需要加载,修改和保存。 如果要添加内容,请创建新对象并保存。

Ebean查看对象的@Id值,而不是列表中对象的索引。如果您的对象没有id,则Ebean会在表中创建新记录。

也许,如果你创建具有相同id的新对象,Ebean将更新它。例如

Item item3 = new Item();
item3.id = cart.items.get(1).id;
item3.name = "Apple";

但是1)我不能告诉你它是否会起作用2)真的 hackish你真的不需要使用它。

如果你想修改items中的对象,你需要加载它并修改加载的对象,这是正确的方法。

答案 1 :(得分:0)

我遇到了类似的问题,但发现解决方案是基于使用setter更改值而不是直接访问字段。我假设有一些魔法被注入到方法中,以通知子系统对象的变化,允许更新等。

所以,是的,我会像这样编写原始示例(假设数据库事先是空的):

Cart cart = new Cart();
Item item1 = new Item(); item1.setName("Banana");
Item item2 = new Item(); item2.setName("Peach");
cart.items = new ArrayList<Item>();
cart.items.add(item1);
cart.items.add(item2);
cart.save();

Cart cart = Cart.find.all().get(0);

Item item1 = cart.items.get(0);
item1.setName("Orange");

Item item2 = cart.items.get(1);
item2.setName("Apple");  

cart.update();

您还可以将最后3行更改为:

Item item2 = new Item();
item2.setId(1); // this way Ebean will do the update
item2.setName("Apple");

cart.update();

希望有所帮助。