我有一个非常满意的现有数据模型:
public class Garden {
private String name; // "Oak Grove"
private List<Plant> plants;
}
public class Plant {
private String name; // "Cherry Tomato"
}
我想在Hibernate中使用以下条件对此进行映射:
Java中的
Plant
类不维护对其父级Garden
的引用。这使Java层IMO的工作更加困难。PLANT
表应具有GARDEN_ID
列,该列是GARDEN(ID)
列的外键。我在
@OneToMany
添加之前的初始设置:@Entity(name = "GARDEN")
public class Garden {
@Id
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "NAME", nullable = false)
private String name; // "Oak Grove"
// Not yet mapped
private List<Plant> plants;
}
@Entity(name = "PLANT")
public class Plant {
@Id
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "NAME", nullable = false)
private String name; // "Cherry Tomato"
}
如何在
@OneToMany
上定义List<Plant> plants;
批注,以使外键引用保留在Plant
中?如果我只添加:
@OneToMany(cascade = { CascadeType.ALL })
@JoinColumn(name = "GARDEN_ID")
private List<Plant> plants;
然后用植物保存花园失败,如下所示:
Caused by: org.h2.jdbc.JdbcSQLException: NULL not allowed for column "GARDEN_ID"; SQL statement:
insert into PLANT (NAME, ID) values (?, ?) [23502-191]
因此看来,Hibernate并没有试图保留外键。有没有办法完全不破坏我的对象模型的方法?
编辑:我正在测试的方式是:
Garden garden = new Garden("Oak Grove");
garden.addPlant(new Plant("Cherry Tomato"));
gardenManager.save(garden);
在其中
save()
方法看起来非常休眠:public void save(T item) {
try (Session session = factory.openSession()) {
Transaction transaction = session.beginTransaction();
try {
session.saveOrUpdate(item);
transaction.commit();
} catch (Exception ex) {
System.out.println("Error occurred saving item: " + ex.getMessage());
ex.printStackTrace();
transaction.rollback();
}
}
}
最佳答案
Yogesh Sakurikar接近了,但是双向@JoinColumn
有点偏离。在下面,您将看到如何双向或单向加入
@Entity(name = "GARDEN")
public class Garden {
@Id
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "NAME", nullable = false)
private String name; // "Oak Grove"
// use this if you don't want a bi-directional relationship
// @OneToMany
// @JoinColumn(name = "ID", referencedColumnName="GARDEN_ID")
// private List<Plant> plants;
// use this if you want it bi-directional
@OneToMany(fetch = FetchType.LAZY, mappedBy = "garden")
private Set<Plant> plants;
}
@Entity(name = "PLANT")
public class Plant {
@Id
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "NAME", nullable = false)
private String name; // "Cherry Tomato"
// use this if you don't want a bi-directional relationship
// @Column(name="GARDEN_ID")
// private long gardenId;
// use this if you want a bi-directional relationship
@ManyToOne
@JoinColumn(name = "GARDEN_ID", referencedColumnName="ID", nullable = false)
private Garden garden;
}
下面的代码假定双向关系。否则,在完全描述任何孩子
Garden.id
之前,您需要了解您的Plant
Garden garden = new Garden("Oak Grove");
Plant plant = new Plant("Cherry Tomato")
plant.setGarden(garden); //don't forget to set the parent on the child
garden.addPlant(plant);
gardenManager.save(garden);