为JPA中的链接表自动生成多对多实体的ID

时间:2015-07-11 21:11:22

标签: oracle hibernate jpa many-to-many sequence

我的问题是,当我在多对多关系中插入实体时,我无法获得在链接表中自动生成的ID。

我在实体Foo和Bar之间有双向的多对多关系。名为FOO_BAR的链接表具有FOO_BAR_ID,FOO_ID和BAR_ID,第一个是表上的PK。它链接FOO和BAR表,它们也有自己的PK,FOO_ID和BAR_ID。这两个扩展自一个公共基类,它具有@Id和序列生成器。

public abstract class ParentEntity {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator =  "generator")
    @SequenceGenerator(name = "generator", sequenceName = "some_sequence")
    protected Long id;
    //...getters/setters
}

实体Foo位于FOO表中,其PK名为FOO_ID。

@Entity
@Table(name = "FOO")
@AttributeOverride(name = "id", column = @Column(name = "FOO_ID"))
public class Foo extends ParentEntity {
    @Column(name = "name")
    protected String name;
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "FOO_BAR",
          joinColumns = @JoinColumn(name = "FOO_ID"),
          inverseJoinColumns = @JoinColumn(name = "BAR_ID"))
    protected Set<Bar> bars;
    //...getters/setters
}

此实体Bar是BAR表,其PK为BAR_ID。

@Entity
@Table(name = "BAR")
@AttributeOverride(name = "id", column = @Column(name = "BAR_ID"))
public class Bar extends ParentEntity {
    @Column(name = "name")
    protected String name;

    @ManyToMany(mappedBy = "bars", cascade=CascadeType.ALL)
    protected Set<Foo> foos;
    //...getters/setters
}

链接表有FOO_ID,BAR_ID和它自己的名为FOO_BAR_ID的PK。

问题在于,当我尝试插入新的Foo时,在FOO_BAR链接表中没有为PK插入ID。其他两个ID看起来很好。

当我坚持使用以下内容时:

@Transactional
public void baz() {
    Foo foo = new Foo();
    Bar bar = entityManager.find(barId);
    foo.setBars(new HashSet<Bar>());
    foo.getBars().add(bar);
    entityManager.persist(foo);
    //also tried .merge just for giggles
}

持续存在是错误发生的地方。查看SQL日志,这是输出的内容:

DEBUG: org.hibernate.SQL - select some_sequence.nextval from dual
DEBUG: org.hibernate.SQL - insert into FOO (FOO_ID, NAME) values (?, ?)
DEBUG: org.hibernate.SQL - insert into FOO_BAR (FOO_ID, BAR_ID) values (?, ?)
WARN : org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 1400, SQLState: 23000
ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - ORA-01400: cannot insert NULL into ("MY_SCHEMA"."FOO_BAR"."FOO_BAR_ID")

这基于SQL执行是有道理的,但我不知道如何让链接表的PK生成。

我相信很多人都可以欣赏,由于客户的限制,这就是必须的方式,但我无法弄清楚这是不可能的,还是我做错了什么。

1 个答案:

答案 0 :(得分:4)

您拥有的两个主要选项是:

1)更改联接表,使其只有FOO_IDBAR_ID,主键是这两个字段的组合,

2)如果您希望连接表不仅包含FOO_IDBAR_ID,那么您需要将连接表定义为单独的实体类(FooBar) 。然后,FooBar都会与FooBar建立一对多关联。