2017-05-10 60 views
1

有2個表。JPA hibernate 4延遲加載問題。如何在沒有渴望的情況下在ManyToOne中加載惰性數據

一個表與另一個表有很多連接。

所有連接都是延遲加載樣式。當我想從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; 

這傢伙是代理,這意味着我不能得到任何數據。 即使我要求得到我沒有得到任何信息。 表1 Table 1

表2 Table 2

所以,如果我從母親表調用。當我們想要時,我們會得到清單。這部分是好的。 enter image description here

現在的問題是,如果我從子表調用哪裏有很多toOne關係。我從那裏得到代理。我沒有收到充足的信息。 如果我做EAGER我會得到它,但我不想那樣。有沒有其他的方式可以讓我在不需要做EAGER的情況下獲得這些惰性數據。 enter image description here

UPDATE 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; 
} 
    } 

的UsersPhotos類

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; 
} 

}

UPDATE 2 我看到,如果我在此UserPhoto對象內調用User的任何setter,那麼它將獲取信息。例如,countryList .get(0).getUser()。getLink()實際上會轉到數據庫並檢索信息。但是,只有那些信息纔會以完整的對象數據響應,我的意思是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語句發生。

+0

請下次複製源代碼而不是打印屏幕,以便它更具可讀性。在你最後的打印屏幕中,你有一個惰性的用戶對象初始化,這可以讓你使用'FetchType.LAZY'。你能告訴你如何訪問用戶數據? –

+0

列表 countryList = session.createQuery(「from UsersPhotos」)。list(); 我稱之爲該用戶數據爲空。我想填充這個用戶數據,但我想保持懶惰。當我想要的時候,有沒有像力量的東西? 要訪問我做countryList .get(0).getUser(),並且這根本不會返回任何東西 – legend12345

+0

我把完整的源代碼 – legend12345

回答

0

試試這個:

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而不是JOIN FETCH所以查詢不會排除UsersPhotos哪些沒有UppeningUsers

List<UsersPhotos> countryList = session.createQuery("from UsersPhotos up LEFT JOIN FETCH up.user").list(); 
+0

是的,這已經成功了。即使它很懶,我可以在列表中獲取特定的項目數據。謝謝你, – legend12345

+0

但問題在於,現在所有的UppeningUser對象懶加載器也加載:)它有3個懶惰加載器。所以他們也來了。 – legend12345

+0

你有什麼建議嗎? – legend12345

0

您可以使用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()); 
} 
+0

抱歉同樣的事情發生。 但是,通過我的調查,我發現如果我在此UserPhoto對象內調用User的任何setter,那麼它將獲取信息。 (0).getUser()。getLink()實際上轉到數據庫並檢索信息..但只有那些信息它不作爲完整的對象數據響應,我的意思是countryList .get(0).getUser () 這個。 我不想去所有的數據,這就是我的問題。 – legend12345

+0

我把完整的源碼 – legend12345

+0

@ legend12345你是對的,觸發獲取延遲初始化實體的方法之一就是在會話內部爲它們調用getter方法,Hibernate.initialize()只是Hibernate提供的一種更清晰的方式只是不要在代碼中調用getter方法而不將它分配給任何變量 – fujy