JPA 休眠 4 延迟加载问题。如何在不急切的情况下在 ManyToOne 中加载惰性数据
JPA hibernate 4 lazy load issue. How to load lazy data in ManyToOne without eager
有 2 个 table。
一个 table 与另一个 table 有很多联系。
所有连接都是延迟加载风格。当我想从 UppeningUsers 那里得到一些东西时,延迟加载起作用了,我可以获取数据。这部分说清楚了。
Session session = this.sessionFactory.getCurrentSession();
List<UppeningUsers> countryList = session.createQuery("from UppeningUsers").list();
如果我调用 listPhotoObj、peopleWhoBlockedMe、peopleIBlocked,这会简单地获取代理,然后它们会被初始化。所以我明白了这部分。
但是如果我调用
Session session = this.sessionFactory.getCurrentSession();
List<UsersPhotos> countryList = session.createQuery("from UsersPhotos").list();
然后
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private UppeningUsers user;
这家伙是代理人,这意味着我无法获得任何数据。
即使我请求 get 我也没有得到任何信息。
Table 1
Table 2
所以如果我从妈妈那里打电话table。我们可以在需要时获得列表。这部分没问题。
现在的问题是,如果我从 child table 那里调用 manytoOne relation.I 从那里获取代理。我没有得到完整的信息。
如果我渴望,我会得到它,但我不想要那样。有没有其他方法可以让我在需要时无需执行 EAGER 即可获得这些惰性数据。
更新 1
package com.uppening.models;
import com.sun.istack.internal.Nullable;
import org.hibernate.annotations.Formula;
import org.hibernate.annotations.Proxy;
import javax.persistence.*;
import java.util.Set;
@Entity
@Table(name = "uppening_users")
@Proxy(lazy = true)
public class UppeningUsers {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
int id;
private String name;
private boolean isblocked;
private String mail;
private String birthday;
private String source;
private String gender;
private String link;
private String description;
private String traveller;
private String interests;
private String device;
private String location;
private String showup;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UsersPhotos> listPhotoObj;
@OneToMany(mappedBy = "personBlocked", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserBlocks> peopleWhoBlockedMe;
@OneToMany(mappedBy = "blocker", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserBlocks> peopleIBlocked;
@OneToMany(mappedBy = "activityUser", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserActivities> listActivities;
@Formula(" DATE_FORMAT( FROM_DAYS( TO_DAYS( NOW( ) ) - TO_DAYS( birthday ) ) , '%Y' ) ")
@Nullable
private Integer age;
public UppeningUsers() {
super();
}
@Transient
public Integer getAge() {
return age;
}
public UppeningUsers(String name, boolean isblocked, String mail, String birthday,
String source, String gender, String link, String description,
String traveller, String interests, String device, String location,
String showup, Set<UsersPhotos> listPhotoObj, Set<UserBlocks> peopleWhoBlockedMe,
Set<UserBlocks> peopleIBlocked, Set<UserActivities> listActivities, Integer age) {
this.name = name;
this.isblocked = isblocked;
this.mail = mail;
this.birthday = birthday;
this.source = source;
this.gender = gender;
this.link = link;
this.description = description;
this.traveller = traveller;
this.interests = interests;
this.device = device;
this.location = location;
this.showup = showup;
this.listPhotoObj = listPhotoObj;
this.peopleWhoBlockedMe = peopleWhoBlockedMe;
this.peopleIBlocked = peopleIBlocked;
this.listActivities = listActivities;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isIsblocked() {
return isblocked;
}
public void setIsblocked(boolean isblocked) {
this.isblocked = isblocked;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTraveller() {
return traveller;
}
public void setTraveller(String traveller) {
this.traveller = traveller;
}
public String getInterests() {
return interests;
}
public void setInterests(String interests) {
this.interests = interests;
}
public String getDevice() {
return device;
}
public void setDevice(String device) {
this.device = device;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getShowup() {
return showup;
}
public void setShowup(String showup) {
this.showup = showup;
}
public Set<UsersPhotos> getListPhotoObj() {
return listPhotoObj;
}
public void setListPhotoObj(Set<UsersPhotos> listPhotoObj) {
this.listPhotoObj = listPhotoObj;
}
public Set<UserBlocks> getPeopleWhoBlockedMe() {
return peopleWhoBlockedMe;
}
public void setPeopleWhoBlockedMe(Set<UserBlocks> peopleWhoBlockedMe) {
this.peopleWhoBlockedMe = peopleWhoBlockedMe;
}
public Set<UserBlocks> getPeopleIBlocked() {
return peopleIBlocked;
}
public void setPeopleIBlocked(Set<UserBlocks> peopleIBlocked) {
this.peopleIBlocked = peopleIBlocked;
}
public Set<UserActivities> getListActivities() {
return listActivities;
}
public void setListActivities(Set<UserActivities> listActivities) {
this.listActivities = listActivities;
}
public void setAge(Integer age) {
this.age = age;
}
}
用户照片Class
package com.uppening.models;
import org.hibernate.annotations.Proxy;
import javax.persistence.*;
@Entity
@Table(name="uppening_resimler")
@Proxy(lazy = true)
public class UsersPhotos {
@Id
@Column(name="id")
@GeneratedValue(strategy= GenerationType.IDENTITY)
int id;
@Column(name="photo")
private
String photo;
public UsersPhotos() {
super();
}
public UsersPhotos(String photo, UppeningUsers user) {
this.photo = photo;
this.user = user;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private UppeningUsers user;
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public UppeningUsers getUser() {
return user;
}
public void setUser(UppeningUsers user) {
this.user = user;
}
}
更新 2
我看到,如果我在此 UserPhoto object 中调用任何 setter 用户,它就会获取信息。例如 countryList .get(0).getUser().getLink() 实际上进入数据库并检索信息..但只有该信息不会作为完整的 object 数据响应,我的意思是 countryList .get(0) .getUser() 这个。我不想获取所有数据,所以这就是我的问题。
更新 3
获取 sql 建议是答案,但它产生了另一个问题
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UsersPhotos> listPhotoObj;
@OneToMany(mappedBy = "personBlocked", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserBlocks> peopleWhoBlockedMe;
@OneToMany(mappedBy = "blocker", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserBlocks> peopleIBlocked;
@OneToMany(mappedBy = "activityUser", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserActivities> listActivities;
这 4 个正在创建 SQL,即使它们是延迟加载。
假设我只想要
private String mail;
private String birthday;
private String source;
private String gender;
private String link;
那么我实际上并不需要那些 sql 发生。
您可以使用 Hibernate.initialize()
触发任何关联数据的提取,只需确保在同一个 session
中使用它
示例:
Session session = this.sessionFactory.getCurrentSession();
List<UsersPhotos> countryList = session.createQuery("from UsersPhotos").list();
for(UsersPhotos usersPhotos : countryList){ // don't forget the null countryList case
Hibernate.initialize(usersPhotos.getUser());
}
试试这个:
List<UsersPhotos> countryList = session.createQuery("from UsersPhotos up JOIN FETCH up.user").list();
检查此以获取更多信息:Difference between JOIN and JOIN FETCH in Hibernate
更新 1:
您可以使用 LEFT JOIN FETCH instead of JOIN FETCH 这样查询就不会排除没有 UppeningUsers
.
的 UsersPhotos
List<UsersPhotos> countryList = session.createQuery("from UsersPhotos up LEFT JOIN FETCH up.user").list();
有 2 个 table。
一个 table 与另一个 table 有很多联系。
所有连接都是延迟加载风格。当我想从 UppeningUsers 那里得到一些东西时,延迟加载起作用了,我可以获取数据。这部分说清楚了。
Session session = this.sessionFactory.getCurrentSession();
List<UppeningUsers> countryList = session.createQuery("from UppeningUsers").list();
如果我调用 listPhotoObj、peopleWhoBlockedMe、peopleIBlocked,这会简单地获取代理,然后它们会被初始化。所以我明白了这部分。
但是如果我调用
Session session = this.sessionFactory.getCurrentSession();
List<UsersPhotos> countryList = session.createQuery("from UsersPhotos").list();
然后
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private UppeningUsers user;
这家伙是代理人,这意味着我无法获得任何数据。
即使我请求 get 我也没有得到任何信息。
Table 1
Table 2
所以如果我从妈妈那里打电话table。我们可以在需要时获得列表。这部分没问题。
现在的问题是,如果我从 child table 那里调用 manytoOne relation.I 从那里获取代理。我没有得到完整的信息。
如果我渴望,我会得到它,但我不想要那样。有没有其他方法可以让我在需要时无需执行 EAGER 即可获得这些惰性数据。
更新 1
package com.uppening.models;
import com.sun.istack.internal.Nullable;
import org.hibernate.annotations.Formula;
import org.hibernate.annotations.Proxy;
import javax.persistence.*;
import java.util.Set;
@Entity
@Table(name = "uppening_users")
@Proxy(lazy = true)
public class UppeningUsers {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
int id;
private String name;
private boolean isblocked;
private String mail;
private String birthday;
private String source;
private String gender;
private String link;
private String description;
private String traveller;
private String interests;
private String device;
private String location;
private String showup;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UsersPhotos> listPhotoObj;
@OneToMany(mappedBy = "personBlocked", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserBlocks> peopleWhoBlockedMe;
@OneToMany(mappedBy = "blocker", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserBlocks> peopleIBlocked;
@OneToMany(mappedBy = "activityUser", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserActivities> listActivities;
@Formula(" DATE_FORMAT( FROM_DAYS( TO_DAYS( NOW( ) ) - TO_DAYS( birthday ) ) , '%Y' ) ")
@Nullable
private Integer age;
public UppeningUsers() {
super();
}
@Transient
public Integer getAge() {
return age;
}
public UppeningUsers(String name, boolean isblocked, String mail, String birthday,
String source, String gender, String link, String description,
String traveller, String interests, String device, String location,
String showup, Set<UsersPhotos> listPhotoObj, Set<UserBlocks> peopleWhoBlockedMe,
Set<UserBlocks> peopleIBlocked, Set<UserActivities> listActivities, Integer age) {
this.name = name;
this.isblocked = isblocked;
this.mail = mail;
this.birthday = birthday;
this.source = source;
this.gender = gender;
this.link = link;
this.description = description;
this.traveller = traveller;
this.interests = interests;
this.device = device;
this.location = location;
this.showup = showup;
this.listPhotoObj = listPhotoObj;
this.peopleWhoBlockedMe = peopleWhoBlockedMe;
this.peopleIBlocked = peopleIBlocked;
this.listActivities = listActivities;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isIsblocked() {
return isblocked;
}
public void setIsblocked(boolean isblocked) {
this.isblocked = isblocked;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTraveller() {
return traveller;
}
public void setTraveller(String traveller) {
this.traveller = traveller;
}
public String getInterests() {
return interests;
}
public void setInterests(String interests) {
this.interests = interests;
}
public String getDevice() {
return device;
}
public void setDevice(String device) {
this.device = device;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getShowup() {
return showup;
}
public void setShowup(String showup) {
this.showup = showup;
}
public Set<UsersPhotos> getListPhotoObj() {
return listPhotoObj;
}
public void setListPhotoObj(Set<UsersPhotos> listPhotoObj) {
this.listPhotoObj = listPhotoObj;
}
public Set<UserBlocks> getPeopleWhoBlockedMe() {
return peopleWhoBlockedMe;
}
public void setPeopleWhoBlockedMe(Set<UserBlocks> peopleWhoBlockedMe) {
this.peopleWhoBlockedMe = peopleWhoBlockedMe;
}
public Set<UserBlocks> getPeopleIBlocked() {
return peopleIBlocked;
}
public void setPeopleIBlocked(Set<UserBlocks> peopleIBlocked) {
this.peopleIBlocked = peopleIBlocked;
}
public Set<UserActivities> getListActivities() {
return listActivities;
}
public void setListActivities(Set<UserActivities> listActivities) {
this.listActivities = listActivities;
}
public void setAge(Integer age) {
this.age = age;
}
}
用户照片Class
package com.uppening.models;
import org.hibernate.annotations.Proxy;
import javax.persistence.*;
@Entity
@Table(name="uppening_resimler")
@Proxy(lazy = true)
public class UsersPhotos {
@Id
@Column(name="id")
@GeneratedValue(strategy= GenerationType.IDENTITY)
int id;
@Column(name="photo")
private
String photo;
public UsersPhotos() {
super();
}
public UsersPhotos(String photo, UppeningUsers user) {
this.photo = photo;
this.user = user;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private UppeningUsers user;
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public UppeningUsers getUser() {
return user;
}
public void setUser(UppeningUsers user) {
this.user = user;
}
}
更新 2 我看到,如果我在此 UserPhoto object 中调用任何 setter 用户,它就会获取信息。例如 countryList .get(0).getUser().getLink() 实际上进入数据库并检索信息..但只有该信息不会作为完整的 object 数据响应,我的意思是 countryList .get(0) .getUser() 这个。我不想获取所有数据,所以这就是我的问题。
更新 3 获取 sql 建议是答案,但它产生了另一个问题
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UsersPhotos> listPhotoObj;
@OneToMany(mappedBy = "personBlocked", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserBlocks> peopleWhoBlockedMe;
@OneToMany(mappedBy = "blocker", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserBlocks> peopleIBlocked;
@OneToMany(mappedBy = "activityUser", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserActivities> listActivities;
这 4 个正在创建 SQL,即使它们是延迟加载。
假设我只想要
private String mail;
private String birthday;
private String source;
private String gender;
private String link;
那么我实际上并不需要那些 sql 发生。
您可以使用 Hibernate.initialize()
触发任何关联数据的提取,只需确保在同一个 session
示例:
Session session = this.sessionFactory.getCurrentSession();
List<UsersPhotos> countryList = session.createQuery("from UsersPhotos").list();
for(UsersPhotos usersPhotos : countryList){ // don't forget the null countryList case
Hibernate.initialize(usersPhotos.getUser());
}
试试这个:
List<UsersPhotos> countryList = session.createQuery("from UsersPhotos up JOIN FETCH up.user").list();
检查此以获取更多信息:Difference between JOIN and JOIN FETCH in Hibernate
更新 1:
您可以使用 LEFT JOIN FETCH instead of JOIN FETCH 这样查询就不会排除没有 UppeningUsers
.
UsersPhotos
List<UsersPhotos> countryList = session.createQuery("from UsersPhotos up LEFT JOIN FETCH up.user").list();