0

我有两个具有一对多关系的表 A 和 B。两个表都有一个 id 字段,它是自动递增的。表 B 也有一个外键字段引用表 A 的 id 字段。

这是 MySQL DB 的表模式:

CREATE TABLE A (
  `id` INT NOT NULL AUTO_INCREMENT,
  `afield` varchar(255),
  PRIMARY KEY  (`id`)
) ;

CREATE TABLE B (
  `id` INT NOT NULL AUTO_INCREMENT,
  `aId` INT NOT NULL,
  `bfield` varchar(255),
  PRIMARY KEY  (`id`),
  FOREIGN KEY (`aId`)REFERENCES A(`id`) ON DELETE CASCADE
) ;

课程:

@Entity
@Table(name = "A")
public class A implements java.io.Serializable {

    private Integer id;
    private String aField;

    private List b;

    public A() {}

    public A(Integer id) {
        this.id = id;
    }

    @Id
    @Column(name = "id", unique = true, nullable = false)
    @GenericGenerator(name = "generator", strategy = "native")
    @GeneratedValue(generator = "generator")
    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name = "AFIELD", length = 50)
    public String getAField() {
        return this.aField;
    }

    public void setAField(String aField) {
        this.aField = aField;
    }

    //mapped by = "a" a is a field in B. Case sensetive @OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "a") 
    public List getB() {
        return b;
    }

    public void setB(List b) {
        this.b = b;
    }
}

@Entity
@Table(name = "B")
public class B implements java.io.Serializable {

    private String bField;
    private Integer id;
    private Integer aId;

    private A a;

    public B() {}

    @Id
    @Column(name = "id", unique = true, nullable = false)
    @GenericGenerator(name = "generator", strategy = "native")
    @GeneratedValue(generator = "generator")
    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name = "aId")
    public Integer getAId() {
        return this.aId;
    }

    public void setAId(Integer aId) {
        this.aId = aId;
    }

    @Column(name = "BFIELD", length = 50)
    public String getBField() {
        return this.bField;
    }

    public void setBField(String bField) {
        this.bField = bField;
    }

    @ManyToOne
    @JoinColumn(name = "aId", insertable = false, updatable = false)
    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }
}

以下是我的测试方法:

public static void main(String[] args) {
    try {
        Configuration cfg = new Configuration().configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session sess = factory.getCurrentSession();
        Transaction tx = sess.beginTransaction();
        A a = new A();
        a.setAField("afield");
        // sess.save(a);
        // sess.flush();

        List < B > bs = new ArrayList < B > ();
        a.setB(bs);
        B b = new B();
        b.setBField("bfield");
        // b.setAId(a.getId());
        bs.add(b);

        sess.saveOrUpdate(a);
        tx.commit();
        factory.close();
    } catch (Throwable ex) {
        throw new ExceptionInInitializerError(ex);
    }
}

启用注释掉的三行后,它工作正常。基本上它从对象 a 获取 id 并将其设置为对象 b。

但我不高兴我需要在保存 b 对象列表之前保存一个对象。无论如何,如果没有三个注释掉的行,它会起作用吗?场景是其他人可能只是创建对象 a 并设置一个列表对象 b 然后保存对象 a,因为他们不知道这两个对象的关系的细节,也不知道架构。

非常感谢任何帮助!

4

1 回答 1

0

请在提交之前花一些时间格式化您的问题。

也就是说:aId表 B 中的列被映射了两次:一次用于aId字段,一次用于a. 此aId列应消失。您应该只有从 B 到 A 的关联。如果您想要 A 和 B 的 ID,只需调用b.getA().getId().

另一个重要的一点是你有一个双向关联。您应该确保实体图是连贯的。如果将 B 添加到 A 的 B 列表中,则还必须在 B 中设置 A 字段:

a.getBs().add(b);
b.setA(a);

Hibernate 只查看关联的一侧就知道要坚持什么。这一面是没有mappedBy属性的那一面。这意味着您绝对必须调用b.setA(a)才能使其工作。

于 2011-10-21T21:39:29.733 回答