休眠:@OneToMany,避免多个选择

问题描述 投票:0回答:2

考虑一个人可以拥有很多汽车的例子。这就是为什么我们使用@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 = ...

java hibernate jpa persistence
2个回答
0
投票

[经过一些实验并在网上搜索后,我发现使用FetchMode.SELECT可以完全满足我的需求,这正是我所要的。我更改了:


-1
投票

创建一个内存转储并进行分析,以查看正在使用所有内存的内存。也许您只需要增加最大堆大小即可。您也可以使其变得懒惰,并在汽车收藏夹中使用Hibernate.initialize。这样,我什至认为可以使用例如SUBSELECT。如果没有帮助,我建议您使用Blaze-Persistence实体视图将加载状态降低到最小,并确定使用SUBSELECT提取策略。

© www.soinside.com 2019 - 2024. All rights reserved.