2013-02-19 17 views
7

Veritabanında birden çok sorguyu önlemek ve bir sorgudaki tüm bilgileri JOIN Getir ve Ben kullanarak almak için Spring Data'da JPQL kullanarak temel bir sorguyu en iyi duruma getirmeye çalışıyorum Bu benim DaoJPQL Join Kaynak verisi ManyToOne birleşimi Spring Data içinde çalışma değil

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=null,role=null,tableName=Business.Countries,tableAlias=country1_,origin=BUSINESS.COAPPLICANTS coapplican0_,columns={coapplican0_.Country_Id ,className=com.medifast.entity.core.Country}}] [select count(ca) from com.medifast.entity.core.CoApplicant ca LEFT JOIN FETCH ca.country LEFT JOIN FETCH ca.state where ca.client.id = :clientId]; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=null,role=null,tableName=Business.Countries,tableAlias=country1_,origin=BUSINESS.COAPPLICANTS coapplican0_,columns={coapplican0_.Country_Id ,className=com.medifast.entity.core.Country}}] [select count(ca) from com.medifast.entity.core.CoApplicant ca LEFT JOIN FETCH ca.country LEFT JOIN FETCH ca.state where ca.client.id = :clientId] 
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:301) 

geçerli::

/** 
* Interface to handle persistence operations for CoApplicants. 
* 
*/ 
@Repository 
public interface ICoApplicantDao extends JpaRepository<CoApplicant, Long> 
{ 
    @Query("select ca from CoApplicant ca JOIN FETCH ca.country c where ca.client.id = :clientId") 
    Page<CoApplicant> findCoApplicantsByClient(@Param("clientId") Long clientId, Pageable pageable); 
} 

Ve bunlar benim varlıklardır:

@Entity 
@Table(name = "BUSINESS.COAPPLICANTS") 
@SQLDelete(sql = "UPDATE BUSINESS.COAPPLICANTS SET DELETED = 1 WHERE id = ?") 
@Where(clause = "DELETED <> 1") 
@Data 
@EqualsAndHashCode(callSuper = true) 
public class CoApplicant extends AbstractAuditableEntity 
{ 

    /** 
    * Serial. 
    */ 
    private static final long serialVersionUID = -297231024073091062L; 


    /** 
    * First name. 
    */ 
    @Column(name = "FirstName") 
    private String firstName; 

    /** 
    * Last name. 
    */ 
    @Column(name = "LastName") 
    private String lastName; 


    /** 
    * Recognition Name. 
    */ 
    private String recognitionName; 

    /** 
    * For the address line 1 field. 
    */ 
    private String addressLine1; 

    /** 
    * For the address line 2 field. 
    */ 
    private String addressLine2; 


    /** 
    * City. 
    */ 
    private String city; 

    /** 
    * State. 
    */ 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "State_Id") 
    private State state; 

    /** 
    * Zip Code. 
    */ 
    private String zipCode; 

    /** 
    * Country. 
    */ 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "Country_Id") 
    private Country country; 

    /** 
    * Email address. 
    */ 
    @Column(unique = true) 
    private String email; 

    /** 
    * Main Phone number. 
    */ 
    private String mainPhone; 

    /** 
    * Constructor. 
    */ 
    public CoApplicant() 
    { 
     super(); 
    } 
} 


/** 
* Country entity. 
*/ 
@Entity 
@Table(name = "Business.Countries") 
@SQLDelete(sql = "Update Business.Countries set deleted = 1 where id=?") 
@Where(clause = "deleted <> 1") 
@Data 
@EqualsAndHashCode(callSuper = true) 
public class Country extends AbstractAuditableEntity 
{ 

    /** 
    * Serial. 
    */ 
    private static final long serialVersionUID = -267110442898674427L; 

    /** 
    * Name of the country. 
    */ 
    private String name; 

    /** 
    * The orders for the client. 
    */ 
    @OneToMany(mappedBy = "country", cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    private Collection<State> states; 

    /** 
    * Const. 
    */ 
    public Country() 
    { 
     super(); 
    }  

} 


    /** 
* State entity. 
*/ 
@Entity 
@Table(name = "Business.States") 
@SQLDelete(sql = "Update Business.States set deleted = 1 where id=?") 
@Where(clause = "deleted <> 1") 
@Data 
@EqualsAndHashCode(callSuper = true) 
public class State extends AbstractAuditableEntity 
{ 

    /** 
    * Serial. 
    */ 
    private static final long serialVersionUID = 8643487990581006632L; 

    /** 
    * Name of the state. 
    */ 
    private String name; 

    /** 
    * Code of the state. 
    */ 
    private String code; 

    /** 
    * Country to which this State belongs. 
    */ 
    @ManyToOne 
    @JoinColumn(name = "Country_Id") 
    private Country country; 


    /** 
    * Constr. 
    */ 
    public State() 
    { 
     super(); 
    } 
} 
bu durum almaya devam

Herhangi bir anlayış, yardım çok takdir edilecektir.

böyle bir şey olmazdı tamamlamasını istediğim için saf SQL:

SELECT ca.Id 
     ,firstName 
     ,lastName 
     ,recognitionName 
     ,addressLine1 
     ,city 
     ,email 
     ,mainPhone 
     ,coun.name 
     ,sta.name 
    FROM coApplicants AS ca 
    LEFT JOIN countries AS coun 
    on ca.country_Id=coun.id 
    LEFT JOIN states AS sta 
    on ca.state_Id=sta.id 
+0

nasıl (ve neden) sadece sayımı dönerken (bir torba getir katılabilir)? –

+0

Hey guido, sadece burada bir çanta neden merak, her CoApplicant sadece bir Devlet ve onunla ilişkili bir Ülke olmalıdır. Kendimi oldukça iyi işler başarmak istediğiniz şey için aşağıdaki saf SQL sorgusu: ca.Id , firstName , lastName , recognitionName , AddressLine1 , şehir , e-posta , mainPhone , coun.name , sta.name SEÇ ca SOL OLARAK coApplicants GELEN ca.country_Id üzerinde \t = coun.id SOL sta OLARAK devletleri KATILIN ülkeleri OLARAK ülkeleri KATILIN ben aynı sorunu var ca.state_Id = sta.id – vanvasquez

+2

üzerine \t, sorun olduğunu " Sayfa "" ve "FETCH" ile değiştirirseniz, listeyi mükemmel şekilde çalışır. Eğer çözüm buldunuz, evet ise lütfen bizimle paylaşın :) –

cevap

10

FETCH JOIN ile pagable sorgu kullanarak Hazırda bir konudur.

Durumu çözmek için countQuery'yi yerleştirmeniz gerekir - orijinal ile neredeyse aynı, ancak ilgisiz INNER JOIN'leri (sonunda FETCH'ler) kaldırılır.

çözümün kaynağı burada bulunamadı: Spring-Data FETCH JOIN with Paging is not working

Yani sizin için çözüm olacaktır:

@Query(
    value="select ca from CoApplicant ca JOIN FETCH ca.country c where ca.client.id = :clientId", 
    countQuery="select count(ca) from CoApplicant ca where ca.client.id = :clientId") 
Page<CoApplicant> findCoApplicantsByClient(@Param("clientId") Long clientId, Pageable pageable); 
+0

Çok teşekkürler joro, önerdiğiniz mükemmel çalışıyor. – vanvasquez

+0

Son olarak, bunu buldum. Çok teşekkürler! –

+0

ama @Query –