Java 休眠:@OneToMany,避免多次选择
举个例子,一个人可以有很多车。这就是我们使用@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
@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>();