【问题标题】:JPA @OneToMany not fetching the childernJPA @OneToMany 不接孩子
【发布时间】:2012-10-12 19:57:56
【问题描述】:

以下是表结构:

desc customer_survey
Name        Null     Type         
----------- -------- ------------ 
SURVEYID    NOT NULL VARCHAR2(10) 
CUSTNO      NOT NULL VARCHAR2(10) 
SRNO                 NUMBER(10)   
AVGRATINGS           NUMBER(5,2)  
COMMENTS             VARCHAR2(50) 
SENTON               DATE         
RESPONDEDON          DATE         

desc Survey_response
Name             Null     Type         
---------------- -------- ------------ 
SURVEYRESPONSEID NOT NULL NUMBER(10)   
RATINGS          NOT NULL NUMBER(2)    
QNO              NOT NULL VARCHAR2(10) 
SURVEYID         NOT NULL VARCHAR2(10) 

Java 类:

 public class CustomerSurvey implements Serializable {

@OneToMany(fetch=FetchType.EAGER, mappedBy="customerSurvey", 
     cascade=CascadeType.ALL)
private Set<SurveyResponse> responses;
 ......

 public class SurveyResponse {

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="SURVEYID", referencedColumnName="surveyId")
private CustomerSurvey customerSurvey;

 ......

客户端代码:

 List<CustomerSurvey> surveys = workService.getSurveysByCustomer("testCNo2");
 System.out.println("surveys size = " + surveys.size());

 for(CustomerSurvey survey: surveys) {
System.out.println("getting responses from the survey object now..");
Set<SurveyResponse> responses = survey.getResponses();
System.out.println("responses size= .." + responses.size());
 }

控制台显示:

调查大小 = 1 立即从调查对象中获取响应.. 响应大小= ..0

而数据库中有 7 个针对所选调查的回复。

【问题讨论】:

    标签: jpa one-to-many eager-loading many-to-one


    【解决方案1】:

    启用日志记录并查看 SQL 是否正确。

    从你不完整的代码很难看出,但一般来说,OneToMany 不应该使用 JoinColumn,它应该使用 mappedBy,并且 ManyToOne 中的连接列应该引用对象的 Id。

    还要确保在插入对象时设置关系的双方。

    【讨论】:

    • 我根据您的评论更改了我的代码。日志文件中的查询显示:SELECT 'com.ge.dsp.iwork.entity.CustomerSurvey' AS NUCLEUS_TYPE,SURVEY.AVGRATINGS,SURVEY.COMMENTS,B0.CITY,B0.COMPANYNAME,B0.CUSTNO,B0.EMAIL,B0.FIRSTNAME ,B0.GENDER,B0.LASTNAME,B0.MIDINIT,B0.PHONE,B0."STATE",B0.STREETADDRESS,B0.TITLE,B0.ZIPCODE,SURVEY.RESPONDEDON,SURVEY.SENTON,C0.CUSTNO,C0.DATECREATED ,C0.DATEUPDATED,C0.DESCRIPTION,C0.SRNO,C0.STATUS,SURVEY.SURVEYID 从 CUSTOMER_SURVEY SURVEY INNER JOIN CUSTOMER B0 ON SURVEY.CUSTNO = B0.CUSTNO LEFT OUTER JOIN SERVICE_REQUEST C0 ON SURVEY.SRNO = C0.SRNO WHERE B0 .CUSTNO =
    【解决方案2】:

    this link 提供帮助。 我将集合设置回惰性。和
    在持久性类内部,在获取结果集后的事务中,我现在将 getResponses 称为:

    List<CustomerSurvey> surveys = query.getResultList();
    for (CustomerSurvey survey : surveys) {
        Set<SurveyResponse> responses = survey.getResponses();
    }
    

    填充响应。

    【讨论】:

      【解决方案3】:

      另一种选择是使用 jpql fetch 查询填充关系:

      “从Surveys调查中选择调查加入获取survey.responses”

      我遇到了同样的问题,但仍然无法找出问题所在。在我的情况下,父实体是由 jpql 查询加载的,因此扩展它提供了一种解决方法

      【讨论】:

      • 它对我有帮助。可能页面en.wikibooks.org/wiki/Java_Persistence/Querying可以在将来帮助某人
      • 我遇到了关于这个解决方案的另一个问题,在我之前的评论中提到:重复数据和巨大的连接连接提取的一个问题是可以返回重复数据。例如,考虑加入获取 Employee 的 phoneNumbers 关系。如果每个 Employee 在其 phoneNumbers 集合中有 3 个 Phone 对象,则连接将需要带回 n*3 行。由于每个员工行有 3 个电话行,因此员工行将被复制 3 次。一种不受重复数据影响的加入 fetch 的替代解决方案是使用 Batch Fetching。
      猜你喜欢
      • 2011-01-01
      • 2017-06-25
      • 1970-01-01
      • 2017-06-23
      • 1970-01-01
      • 2023-03-20
      • 2017-08-31
      • 2021-12-01
      相关资源
      最近更新 更多