【问题标题】:How to update a many to many relationship in Play framework 2 and ebean?如何更新 Play framework 2 和 ebean 中的多对多关系?
【发布时间】:2013-01-18 05:09:33
【问题描述】:

如何在 Play 框架 2 和 ebean 中更新多对多关系?我不断收到这样的错误:

[PersistenceException: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "pk_field_event" Detail: Key (field_id, event_id)=(3, 21) already exists.]

我正在尝试使用表单选择哪些字段属于某个事件。我提交了一个包含字段列表的表单。 id 属性是唯一填充的属性。然后我执行以下操作:

Event event = Event.find(eventId);
event.fields = fieldsForm.get().fields;
event.update();

我还尝试从数据库中加载每个字段,将事件添加到其中,然后在该字段上调用 ​​update()。

这是我的课程:

注意:为简单起见,我删除了 Entity 和 Id 注释。

public class Event {
    @ManyToMany(cascade = CascadeType.ALL, mappedBy = "events")
        public List<Field> fields;
    }
}

public class Field {
    @ManyToMany(cascade = CascadeType.ALL)
    public List<Event> events;
}

【问题讨论】:

    标签: playframework many-to-many playframework-2.0 updating ebean


    【解决方案1】:

    我不确定这是否是正确的方法,但它似乎可以解决问题。我只需拨打updateFields()

    public static void removeField(Long eventId, Long fieldId) {
        Event event = Event.find.setId(eventId).fetch("fields").findUnique();
        event.fields.remove(Field.find.ref(String.valueOf(fieldId)));
        event.saveManyToManyAssociations("fields");
    }
    
    public static void updateFields(Long eventId, List<Field> fields) {
        Event event = find.setId(eventId).fetch("fields").findUnique();
    
        for(Field field : event.fields) {
            removeField(eventId, field.id);
        }
        for (Field field : fields) {
            if (field.id != null) {
                event.fields.add(Field.find.ref(String.valueOf(field.id)));
            }
        }
        event.saveManyToManyAssociations("fields");
    }
    

    【讨论】:

      【解决方案2】:

      我也有类似的问题。而不是:

      Event event = Event.find(eventId);
      event.fields = fieldsForm.get().fields;
      event.update();
      

      我愿意

      Event event = Event.find(eventId);
      event.fields.clear();
      event.fields.addAll(fieldsForm.get().fields);
      event.update();
      

      这就是诀窍。但是我仍在寻找更好的解决方案。

      【讨论】:

      • 如果有更好的解决方案,那就很复杂了。
      【解决方案3】:

      我把丹尼斯的解决方案放在一个通用函数中:

      public static <T> void replaceItems(Function0<List<? super T>> fn,
                                          Collection<? extends T> newItems) {
          List<? super T> oldItems = fn.apply();
          oldItems.clear();
          oldItems.addAll(newItems);
      }
      

      像这样使用它:

      replaceItems(event::fields, formFields.get().fields);
      

      我传递了一个函数来帮助确保您以正确的顺序放置参数。此解决方案需要 Java 8+。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多