考虑一个人可以拥有很多汽车的例子。这就是为什么我们使用@OneToMany批注的原因:
@Entity
@Table(name = "person")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "phone")
private String phone;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "owner")
private List<Car> cars = new ArrayList<Car>();
public Person() {
}
// Getters setters
}
@Entity
@Table(name = "cars")
public class Car {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@ManyToOne
private Person owner;
@Column(name = "description")
private String description;
public Car() {
}
// Getters setters
坚持不懈,一切正常,但是我想更改一些东西以满足我的需求。程序启动时,我希望所有人都被加载到内存中,例如在List<Person>
中。所以,我这样做:
List<Person> persons = session.createQuery("from Person", Person.class).list();
但是,从意义上讲,Hibernate也要装载汽车。 是否有办法阻止它执行此操作?
之所以这样,是因为它可以更快地执行以下操作:
List<Person> persons = loadAllPersonsFromDatabase();
List<Car> allCars = loadAllCarsFromDatabase();
for (Person p : persons)
{
List<Car> carsOfThisPerson = findCarsOfThisPerson(allCars,p);
p.setCars(carsOfThisPerson);
}
因为我想把所有东西都留在内存中。
我知道在内存中加载数据库的所有记录不是一种常见的做法,其原因是因为一个是数据库而另一个是内存。但是,我的环境是台式机连接,查询有点慢(因为数据库是独立的),并且我敢肯定,这些记录将永远不会导致OutOfMemoryError
。
[我认为提到FetchType.EAGER
更改为FetchType.LAZY
不会起作用。这是相同的,因为加载数据后,我将所有人称为getCars()
。
@ crizis评论中有一个要点。我之所以不简单删除这两个(Person,Car)的关系(做@Transient List<Car> cars
),是因为我想拥有持久性提供的其他功能。我的意思是,如果我这样做:
Car car = getCarByPerson("John"); car.setDescription("John");
我可以通过以下方式保存这辆车:
hibernateSession.save(john);
而不是:
hibernateSession.save(car);
此外,如果我删除John,我也希望删除他的所有汽车(这是CASCADE
所在的位置,而不必强迫我:
for (Car c : john.getCars()) hibernateSession.delete(c);
或其他。
考虑一个人可以拥有很多汽车的例子。这就是为什么我们使用@OneToMany注释的原因:@Entity @Table(name =“ person”)公共类Person {@Id @GeneratedValue(strategy = ...
[经过一些实验并在网上搜索后,我发现使用FetchMode.SELECT
可以完全满足我的需求,这正是我所要的。我更改了:
创建一个内存转储并进行分析,以查看正在使用所有内存的内存。也许您只需要增加最大堆大小即可。您也可以使其变得懒惰,并在汽车收藏夹中使用Hibernate.initialize
。这样,我什至认为可以使用例如SUBSELECT。如果没有帮助,我建议您使用Blaze-Persistence实体视图将加载状态降低到最小,并确定使用SUBSELECT提取策略。