Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 休眠:@OneToMany,避免多次选择_Java_Hibernate_Jpa_Persistence - Fatal编程技术网

Java 休眠:@OneToMany,避免多次选择

Java 休眠:@OneToMany,避免多次选择,java,hibernate,jpa,persistence,Java,Hibernate,Jpa,Persistence,举个例子,一个人可以有很多车。这就是我们使用@OneToMany注释的原因: @Entity @Table(name = "person") public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(name = "first_name") private String firstName; @C

举个例子,一个人可以有很多车。这就是我们使用@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
}
坚持和一切都很好,但我想改变一些东西来满足我的需要。当程序启动时,我希望所有人都被加载到内存中,比如在
列表中。因此,我这样做:

List<Person> persons = session.createQuery("from Person", Person.class).list();
Car car = getCarByPerson("John");
car.setDescription("John");
我可以通过以下方式拯救这辆车:

hibernateSession.save(john);
而不是通过:
hibernateSession.save(car)

此外,如果我删除John,我希望他的所有汽车也被删除(这就是
CASCADE
的作用),而不必强迫我:

for (Car c : john.getCars())
    hibernateSession.delete(c);

或者别的什么。

创建一个内存转储并分析它,看看是什么在使用所有的内存。也许您只需要增加最大堆大小。 您还可以将其设置为惰性,并对cars集合使用
Hibernate.initialize
。这样,我甚至认为可以使用诸如SUBSELECT之类的获取模式。
如果没有任何帮助,我可以建议使用Blaze Persistence实体视图将加载状态降至最低,并使用SUBSELECT获取策略。

经过一些实验并在web上搜索后,我发现使用
获取模式。SELECT
将完全满足我的要求,这正是我想要的。我改变了:

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "owner")
private List<Car> cars = new ArrayList<Car>();
@OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL,mappedBy=“owner”)
私家车列表=新的ArrayList();
致:

@OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL,mappedBy=“owner”)
@Fetch(值=FetchMode.SUBSELECT)
私家车列表=新的ArrayList();

事实上,它只做2个选择。

请检查这篇文章,因此,您希望
Person.cars
得到填充,而不是
Car.owner
?为什么不简单地将关联设置为单向,并将
@JoinColumn@Fetch(JOIN)
放在
Person.cars上?这样,您的查询将像您一样将所有内容加载到内存中wanted@crizzis我希望填充人员,但当我点击
person.getCars()
时,列表将为空。然后我会自己手动填写这些汽车清单。很抱歉,我还是不懂。如果你不想让JPA管理
Person.cars
属性,那么你为什么要把它作为协会的一部分呢?只需将其标记为
@Transient
@crizzis我更新了我的问题以回答您。
for (Car c : john.getCars())
    hibernateSession.delete(c);
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "owner")
private List<Car> cars = new ArrayList<Car>();
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "owner")
@Fetch(value = FetchMode.SUBSELECT)
private List<Car> cars = new ArrayList<Car>();