3

我在 ORM 类层次结构中的对象上的连接表存在问题,由于滞后的数据库结构,连接列不是基类的主键。以下是表格设计的示例:

CREATE TABLE "SCH"."FOO"
(
        "OWNERID"       NUMBER(10,0) NOT NULL ENABLE,
        "FOOID"         NUMBER(10,0) NOT NULL ENABLE,
        CONSTRAINT "FOO_PK" PRIMARY KEY ("OWNERID", "FOOID")
        CONSTRAINT "FOO_FK1" FOREIGN KEY ("OWNERID") REFERENCES "SCH"."OWNERS" ("OWNERID") ENABLE
)

CREATE TABLE "SCH"."BAR"
(
        "BARID"             NUMBER(10,0) NOT NULL ENABLE,
        "FOOID"             NUMBER(10,0)
        CONSTRAINT "BAR_PK" PRIMARY KEY ("BARID")
)

这是映射(删除了不必要的信息)

@Entity
@IdClass(FooId.class)
@Table(name = "FOO")
public class Foo implements java.io.Serializable
{
    @Id
    @Column(name = "OWNERID")
    private BigInteger ownerId;

    @Id
    @SequenceGenerator(name = "FOO_GENERATOR", sequenceName = "SEQ_FOO")
    @GeneratedValue(generator = "FOO_GENERATOR")
    @Column(name = "FOOID")
    private BigInteger id;

    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "FOOID", referencedColumnName = "FOOID")
    @Fetch(value = FetchMode.SUBSELECT)
    @Cascade(value = {CascadeType.ALL})
    private Set<Bar> bar = new LinkedHashSet<Bar>(0);
}


@Entity
@Table(name = "BAR")
public class Bar implements java.io.Serializable
{
    @Id
    @Column(name = "BARID")
    private BigInteger id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "FOOID", referencedColumnName = "FOOID")
    private Foo foo;
}

这失败了,但有一个例外:

Caused by: org.hibernate.AnnotationException: referencedColumnNames(FOOID) of com.package.Bar.foo referencing com.package.Foo not mapped to a single property
    at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:204)
    at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:114)
    at org.hibernate.cfg.Configuration.processEndOfQueue(Configuration.java:1580)
    at org.hibernate.cfg.Configuration.processFkSecondPassInOrder(Configuration.java:1503)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1419)
    at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1375)

你能帮忙解决一下吗?

4

3 回答 3

5

您不能两次映射双向关联。单面必须标记为多面的反面,使用mappedBy属性:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "foo")
@Fetch(value = FetchMode.SUBSELECT)
@Cascade(value = {CascadeType.ALL})
private Set<Bar> bar = new LinkedHashSet<Bar>(0);

...

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "FOOID", referencedColumnName = "FOOID")
private Foo foo;

没有理由告诉 Hibernate 两次关联是由连接列 FOOID 映射的。而且这样做实际上是一个错误,因为它定义了两个不同的单向关联,而不是一个双向关联。

编辑

以上应该可以工作,但不是由于以下 Hibernate 错误:这是一个 Hibernate 错误。见HHH-4284

为了规避这个问题,由于FOOID足以确保唯一性,因此解决方案是@Id从所有者 ID 和注释中删除@IdClass注释。

于 2012-06-05T10:12:16.983 回答
1

你可以做如下......它应该工作 -

@Entity
@IdClass(FooId.class)
@Table(name = "FOO")
public class Foo implements java.io.Serializable
{
    @Id
    @Column(name = "OWNERID")
    private BigInteger ownerId;

    @Id
    @SequenceGenerator(name = "FOO_GENERATOR", sequenceName = "SEQ_FOO")
    @GeneratedValue(generator = "FOO_GENERATOR")
    @Column(name = "FOOID")
    private BigInteger id;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "FOOID",nullable=false)
    @ForeignKey(name = "fk")     
    private Set<Bar> bar = new LinkedHashSet<Bar>(0);
}


@Entity
@Table(name = "BAR")
public class Bar implements java.io.Serializable
{
    @Id
    @Column(name = "BARID")
    private BigInteger id;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "FOOID", updatable = false, insertable = false, nullable=false)  
     private Foo foo;
}
于 2012-06-05T10:05:03.643 回答
0

您在 FOO 表中使用了复合主键。因此,您应该尝试@EmbeddedId 属性,并且您应该需要 BAR 实体中与 FOO 实体连接的两列“OWNER_ID”和“FOO_ID”。

于 2012-06-05T10:51:55.923 回答