具有多对多关系的多个表中的JPA查询

时间:2016-04-02 12:19:31

标签: java mysql spring hibernate jpa

有三个表:HospitalMedical_ServiceLanguage_Service, 医院可以提供医疗服务和语言服务。所以有两对多关系。

Simple ERD

现在,我想使用postcode = 3000medical service = Emergency搜索医院数据。

DaoImpl:

public List<Hospital> findByPostcodeAndMedicalType(String postcode, String medical) {
        String str = "SELECT h FROM Hospital h INNER JOIN Medical_Service m ON h.hospital_id = m.hospital_id WHERE " 
                + "h.Postcode = :postcode AND m.Medical_name = :medical";
        Query query = em.createQuery(str);
        query.setParameter("postcode", postcode);
        query.setParameter("medical", medical);
        return query.getResultList();

    }

此外,如果我想从三个表中搜索邮政编码,医疗类型和语言,如何编写jsql。

警告:

  

错误:org.hibernate.hql.internal.ast.ErrorCounter - 加入的路径!    加入的路径!       在org.hibernate.hql.internal.ast.HqlSqlWalker.createFromJoinElement(HqlSqlWalker.java:378)       在org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.joinElement(HqlSqlBaseWalker.java:3858)       在org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3644)

     
    

2016年4月2日下午10:54:30 org.apache.catalina.core.StandardWrapperValve调用     严重:Servlet [appServlet]的Servlet.service()在路径[/ travel]的上下文中引发异常[请求处理失败;嵌套异常是java.lang.IllegalArgumentException:org.hibernate.QueryException:无法解析属性:postcode :com.health.entity.Hospital [SELECT h FROM com.health.entity.Hospital h INNER JOIN Medical_Service m ON h.hospital_id = m.hospital_id WHERE h.Postcode =:postcode AND m.Medical_name =:medical]]有根本原因     org.hibernate.QueryException:无法解析属性:邮政编码:com.health.entity.Hospital         在org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:83)         在org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:77)         在org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1978)         at org.hibernate.hql.internal.ast.tree.FromElementType.getPropertyType(FromElementType.java:367)

  

Hospital.class

@Entity
@Table(name = "Hospital")
public class Hospital {

@Id
@GeneratedValue
    private int hospital_id;

    private String hospital_name;

    private String postcode;

    private String suburb;

    private String address;

    private String type;

    private String category;

    private String longitude;

    private String latitude;

    private String email;

    private String website;

    private String phoneno;

    private String isemergency;

    private String agencytype;

    private String fax;

    @ManyToMany
    @JoinTable(
        name = "Hospital_Medical",
        joinColumns=@JoinColumn(name="Hospital_id", referencedColumnName="Hospital_id"),
        inverseJoinColumns=@JoinColumn(name="Medical_id", referencedColumnName="Medical_id"))
private List<MedicalService> services;

    @ManyToMany
    @JoinTable(
        name = "Hospital_Language",
        joinColumns=@JoinColumn(name="Hospital_id", referencedColumnName="Hospital_id"),
        inverseJoinColumns=@JoinColumn(name="Language_id", referencedColumnName="Language_id"))
private List<Language> languages;

//Setter and Getter
}

MedicalService.class

@Entity
@Table(name = "Medical_Service")
public class MedicalService {

@Id
private int medical_id;

private String medical_name;

private String description;

@ManyToMany(mappedBy="services")
private List<Hospital> hospitals;
//Setter and Getter
}

Language.class

@Entity
@Table(name = "Language")
public class Language {

@Id
private int language_id;

private String language_name;

private String display_name;

@ManyToMany(mappedBy="languages")
private List<Hospital> hospitals;
//Setter and Getter
}

1 个答案:

答案 0 :(得分:0)

我认为您的查询可能有误,这可能是问题的原因。

您目前正在使用:

#include <IE.au3>
$oIE = _IECreate("http://www.google.com")
$oAs = _IETagnameGetCollection($oIE, "input")
$i = 1
For $oA In $oAs
   If $i = 4 Then _IEPropertySet($oA, "innertext", "MyValue")
   $i = $i + 1
Next  

问题可能是Medical_Service不包含Hospital_id字段(在JOIN中使用)。

如果您乐意使用原生查询,可以执行以下操作:

 SELECT h FROM Hospital h
     INNER JOIN Medical_Service m ON h.hospital_id = m.hospital_id
     WHERE h.Postcode = :postcode AND m.Medical_name = :medical

内部SELECT获取提供紧急服务的医院的所有Hospital_id。然后外部选择选择Hospital_id在内部SELECT中的所有医院(即他们提供紧急服务),但也选择那些邮政编码为3000的医院。

要使用原生查询,您可以执行以下操作:

 SELECT * FROM Hospital WHERE Postcode = 3000 AND Hospital_id IN
    (SELECT Hospital_id FROM Hospital_Medical hm INNER JOIN Medical_Service m ON hm.Medical_id = m.Medical_id
    where Medical_name = 'Emergency')