2015-12-07 42 views
0

我有三個實體DrmAdvertisement,DrmCategoryAdvertisementDrmCategory。現在,我想在我的倉庫,執行以下的數據庫查詢,彈簧數據與實體關聯問題

SELECT a.* 
FROM drm_advertisement a 
JOIN drm_category_advertisement ac ON ac.adid = a.adid 
where a.adtype = 'National' 
and ac.categoryid = 2; 

所以我創建了存儲庫DrmAdvertisement如下,

public interface AdvertisementRepository extends 
     CrudRepository<DrmAdvertisement, Long> { 

@Query("SELECT a FROM DrmAdvertisement a join DrmCategoryAdvertisement ac ON ac.adid = a.adid where a.adType = :adType and ac.categoryid = :categoryid") 
    public List<DrmAdvertisement> findAdByCategory(@Param("adType") String adType, @Param("categoryid") Long categoryid); 


} 

但正如我們所知道JPQL聯接依靠實體之間的關聯,並不在ON子句上。那麼如何用ON子句寫查詢呢?

我錯過了我的代碼中的其他東西嗎?我收到以下錯誤,

java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join! [SELECT a FROM com.dooreme.domain.DrmAdvertisement a join DrmCategoryAdvertisement ac ON ac.adid = a.adid where a.adType = :adType and ac.categoryid = :categoryid] 
    org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1679) 
    org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602) 
    org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608) 
    org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:294) 
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 

我的實體類,

DrmAdvertisement:

@Entity 
@Table(name = "drm_advertisement") 
public class DrmAdvertisement implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue 
    private long adId; 

    @Column(nullable = false) 
    private UUID uuid; 

    @Column(nullable = true) 
    private String adName; 

    @Column(nullable = true) 
    private String adDetails; 

    @Column(nullable = true) 
    private String adType; 

    @OneToOne(fetch = FetchType.LAZY) 
    @JoinTable(name = "drm_category_advertisement", joinColumns = @JoinColumn(name = "adid"), inverseJoinColumns = @JoinColumn(name = "categoryId")) 
    private DrmCategory drmCategory; 
} 

DrmCategory

@Entity 
@Table(name = "drm_category") 
@NamedQuery(name = "DrmCategory.findAll", query = "SELECT d FROM DrmCategory d") 
public class DrmCategory implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue 
    private long categoryId; 

    @Column(nullable = false) 
    private UUID uuid; 

    @Column(nullable = true) 
    private String categoryName; 

    @Column(nullable = false) 
    private long parentId; 

    @Column(nullable = true) 
    private String path; 

    @Column(nullable = true) 
    private Date createDate; 

    @Column(nullable = true) 
    private Date modifiedDate; 

    @Column(nullable = true) 
    private boolean active; 

    @OneToMany(fetch = FetchType.LAZY) 
    @JoinTable(name = "drm_category_advertisement", joinColumns = @JoinColumn(name = "categoryId"), inverseJoinColumns = @JoinColumn(name = "adid")) 
    private Set<DrmAdvertisement> drmAdvertisementSet; 

} 

DrmCategoryAdvertisement

@Entity 
@Table(name = "drm_category_advertisement") 
@NamedQuery(name = "DrmCategoryAdvertisement.findAll", query = "SELECT d FROM DrmCategoryAdvertisement d") 
public class DrmCategoryAdvertisement implements Serializable{ 

    private static final long serialVersionUID = 1L; 

    @EmbeddedId 
    private CatAdvId catAdvId; 

    // bi-directional many-to-one association to DrmAdvertisement 
    @OneToOne 
    @JoinColumn(name = "adId", referencedColumnName = "adid", insertable = false, updatable = false) 
    private DrmAdvertisement drmAdvertisement; 

    // bi-directional many-to-one association to DrmSubscriber 
    @OneToOne 
    @JoinColumn(name = "categoryId", referencedColumnName = "categoryid", insertable = false, updatable = false) 
    private DrmCategory drmCategory; 
} 

CatAdvId

@Embeddable 
public class CatAdvId implements Serializable { 

    private static final long serialVersionUID = 1L; 
    private static final int THIRTYTWO = 32; 
    private static final int THIRTYTHREE = 32; 

    private long categoryId; 
    private long adId; 

    public CatAdvId() 
    { 

    } 

    public CatAdvId(long categoryId, long adId) 
    { 
     this.categoryId = categoryId; 
     this.adId = adId; 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Object#hashCode() 
    */ 
    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + (int) (adId^(adId >>> THIRTYTWO)); 
     result = prime * result + (int) (categoryId^(categoryId >>> THIRTYTHREE)); 
     return result; 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Object#equals(java.lang.Object) 
    */ 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     CatAdvId other = (CatAdvId) obj; 
     if (adId != other.adId) 
      return false; 
     if (categoryId != other.categoryId) 
      return false; 
     return true; 
    } 

} 
+0

的可能的複製[休眠4.3.6 QuerySyntaxException:路徑預期的加入(http://stackoverflow.com/questions/ 25839985/hibernate-4-3-6-querysyntaxexception-path-expected-for-join) –

+0

試過這個還是拋出一些異常。我更新了我的問題與實體 –

回答

1

你必須映射DrmAdvertisement和DrmCategoryAdvertisement之間的關係,那麼你的查詢將是:

SELECT a FROM DrmAdvertisement a where a.adType = :adType and a.drmCategory.categoryId = :categoryid 

編輯:

你可以刪除你的映射DrmCategoryAdvertisement和CatAdvId和使用「的mappedBy」在DrmCategory:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "drmCategory") 
private Set<DrmAdvertisement> drmAdvertisementSet; 
+0

它不工作。讓我通過添加實體來編輯我的問題 –

+0

我編輯了我的答案以適合您的映射。 –

+0

謝謝@Adrien。這是工作。你能解釋我如何工作,也是我的映射是正確的還是映射所需的任何修改? –