3

我有一个应该是多对多(双向)的列表

这是过滤器类:

@ManyToMany(targetEntity=Serving.class)
@JoinTable(name = "BRIDGE_SERV_FILTER", joinColumns={
    @JoinColumn(name="filter_id")}, inverseJoinColumns={@JoinColumn(name="serving_id")})
private List<Serving> servings;
public List<Serving> getServing() { return this.servings; }
public void setServing(List<Serving> servings) { this.servings = servings; }

这是服务类:

@ManyToMany(targetEntity=Filter.class)
    @JoinTable(name = "BRIDGE_SERV_FILTER", joinColumns={
        @JoinColumn(name="serving_id")}, inverseJoinColumns={@JoinColumn(name="filter_id")})
    private List<Filter> filters;
    public List<Filter> getFilters() { return filters;}
    public void setFilters(List<Filter> filters) { this.filters = filters;}

然后我应该调用一些东西来从服务中获取所有过滤器,这就是我所做的(服务是服务类型):

List<Filter> filters = serv.getFilters();

//iterate from all filter
for(Filter allf : allFilter)
{
    boolean mark_this = false;
    //..and matched the currently-iterated-all-filters with filter from
    //which the serving got
    for(com.pos.model.Filter f : filters)
    {
        //if matched, mark this current filter
        if (allf.getId().equals(f.getId()))
            mark_this = true;
    }
    tmodel.addRow(new Object[] { allf.getName(), mark_this });
}

该方法在模型中定义,并且是静态的。因此,当表单加载时,它会调用 jTable.setTableModel(Filter.toTableModel(thisServing));

它读取并显示数据。然而,Hibernate 也调用了 delete:

Hibernate: select filter0_.filter_id as filter1_2_, filter0_.is_showable as is2_2_, filter0_.name as name2_ from DIM_FILTER filter0_ where is_showable=true
Hibernate: select filters0_.serving_id as serving1_4_1_, filters0_.filter_id as filter2_6_1_, filter1_.filter_id as filter1_2_0_, filter1_.is_showable as is2_2_0_, filter1_.name as name2_0_ from BRIDGE_SERV_FILTER filters0_ inner join DIM_FILTER filter1_ on filters0_.filter_id=filter1_.filter_id where filters0_.serving_id=?
Hibernate: delete from BRIDGE_SERV_FILTER where serving_id=?

事实上,我根本不做任何删除,也不要求hibernate删除任何东西。可能会发生我不明白的事情......如何防止Hibernate被删除?还是我做错了什么?

4

2 回答 2

2

在代码中的某处,您必须清除服务的过滤器集合,或将此集合设置为空。Hibernate 使这种变化持久化。

另请注意,您的映射是错误的,这就是您看到奇怪行为的原因。您有两个不相关的单向ManyToMany,而不是双向ManyToMany,它们都使用相同的连接表。必须选择一侧作为另一侧的反面。例如,如果您希望过滤器端成为关联的所有者,则必须使用mappedBy属性将服务端标记为反向端:

class Filter {
    @ManyToMany
    @JoinTable(name = "BRIDGE_SERV_FILTER", joinColumns={
    @JoinColumn(name="filter_id")}, inverseJoinColumns={@JoinColumn(name="serving_id")})
    private List<Serving> servings;
}

class Serving {
    @ManyToMany(mappedBy = "servings")
    private List<Filter> filters;
}

这在文档中有所描述。

于 2012-12-29T08:25:26.180 回答
0

这个问题其实从8天前就已经在我身上了,让我很无奈。

问题在于我如何获取列表()。所以......如果你有双向关系,不要做这样的事情:

Long id = getIdFromCombo();
Serving s = (Serving) session.getId(Serving.class, id).uniqueResult();

当您同时初始化表单时:

Public theFormName(Menu m){
  this.menu = m;
}

如果 Menu 将 Serving 设置为一对多,则最好不要针对会话查询 Serving 。最好在以下位置一一匹配:

Serving s;
for(int i=0; i<this.menu.getServings().size(); i++)
{
  if(equal code) s = menu.getServings().get(i);
}

那么你应该不会遇到我上面列出的问题。这很奇怪。陷阱。我想知道是否有人遇到过这个问题。要么这是我的错,要么是一个错误,我不确定。

因为我仍然不明白为什么同时查询 Serving 类(通过 Session 的帮助)是错误的,所以有一个 menu.getServings() 也可以提供您的服务(但视角较少(因为你得到服务的地方是 serving.menu.id = menu.id),无论如何,没关系)

于 2012-12-29T14:24:22.637 回答