1

我有两个简单的实体问题标签,以及它们之间的many-to-many关系。一切正常,除非我想删除导致此异常的问题:Ebean.delete(Issue.class, id)

javax.persistence.PersistenceException: Query threw SQLException:Unknown column
 'issue_id' in 'where clause' 
Bind values:[1b7e5955c26b51dex546fca27x13cc54c2531x-7fef, ] 
Query was:
select t0.id c0 
from tag t0 
where issue_id=?  

非常奇怪的是,生成的 SQL 显然是错误的。它尝试访问表issue_id中的antag但没有。我希望这不是 Ebean 中的错误,而只是我的一个错误,但我不知道它可能是什么。

这是实体 bean(我删除了 getter/setter)和 Ebean 生成的 DDL:

发行实体

@Entity
public class Issue {

    @Id @Column(length=64)
    private String id;    // <-- I use assigned ids
    @Version
    private Date timeStamp;
    private String title;
    private String description;
    private String createdBy;
    @CreatedTimestamp
    private Date createdAt;
    private String state;
    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(
        name="issue_tag",
        joinColumns={@JoinColumn(name="issue_id", referencedColumnName="id")},
        inverseJoinColumns={@JoinColumn(name="tag_id", referencedColumnName="id")})
    private Set<Tag> tags;
}

标记实体

@Entity
public class Tag {

    @Id @Column(length=64)
    private String id;    // <-- I use assigned ids
    @Version
    private Date timeStamp;
    private String name;

    @ManyToMany(mappedBy="tags", cascade=CascadeType.ALL)
    private Set<Issue> issues;
}

生成的 DDL

create table issue (
  id                        varchar(64) not null,
  title                     varchar(255),
  description               varchar(255),
  created_by                varchar(255),
  state                     varchar(255),
  time_stamp                datetime not null,
  created_at                datetime not null,
  constraint pk_issue primary key (id))
;

create table tag (
  id                        varchar(64) not null,
  name                      varchar(255),
  time_stamp                datetime not null,
  constraint pk_tag primary key (id))
;

create table issue_tag (
  issue_id                       varchar(64) not null,
  tag_id                         varchar(64) not null,
  constraint pk_issue_tag primary key (issue_id, tag_id))
;

alter table issue_tag add constraint fk_issue_tag_issue_01 foreign key (issue_id) references issue (id) on delete restrict on update restrict;

alter table issue_tag add constraint fk_issue_tag_tag_02 foreign key (tag_id) references tag (id) on delete restrict on update restrict;
4

1 回答 1

0

这里的主要问题是您在many-to-many关系上设置了删除级联。删除操作的级联应该小心。它只能设置在or的one一侧。 one-to-oneone-to-many

删除应该只级联到不能单独存在的对象。因此,如果我们有班级Person,我们可以在地址列表或与附加信息的班级的关系上设置删除级联。为什么在关系上设置删除级联many-to-many是错误的?想象一下我们在学生和课程之间有这样的关系。我们在两个方向都删除了cascane。现在取消一门课程将导致所有注册该课程的学生被大学除名。同样,移除一名学生会导致取消他注册的所有课程。

在您的代码中,您在两个关系方向都有删除级联。事实证明,这对 Ebean 来说太难了。但是假设 Ebean 完全按照你告诉他的做了。这将是一场灾难。为什么?

  1. 您正在Issue删除id=1
  2. 删除级联到与此问题相关的所有标签。
  3. 删除级联到与上一点删除的所有标签相关的所有问题
  4. 回到 2。

因此,如果所有问题和标签都连接在网络中,那么删除其中一个将导致整个网络的删除。

如果您删除这些级联,那么您的代码将正常工作。
删除问题将导致:

  • issue从表中删除一行
  • issue_tag表中删除适当的行
于 2015-01-31T17:01:14.057 回答