我有两张表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,因为他们不知道两个对象的关系的细节,他们也不知道架构。
非常感谢任何帮助!
答案 0 :(得分:0)
请在提交之前花一些时间格式化您的问题。
即:表B中的aId
列已映射两次:一次用于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)
才能使其正常运行。