Hibernate HQL Join 与复合键
Posted
技术标签:
【中文标题】Hibernate HQL Join 与复合键【英文标题】:Hibernate HQL Join with composite Key 【发布时间】:2014-12-30 23:31:50 【问题描述】:我在尝试编写 HQL 查询时遇到了一些问题 加入如下定义的两个实体/表
CustomersDAO.java
@Entity
@Table(name="customers")
public class CustomerDAO implements Serializable
private static final long serialVersionUID = 1L;
@EmbeddedId
private CustomerNaming name;
@ManyToOne
@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
@JoinColumns( @JoinColumn (name="city"), @JoinColumn(name="state"),@JoinColumn(name="via") )
private Address indirizzo;
@Column (name="email")
private String email;
@Column (name="mailinglist")
private boolean mailinglist;
@Column (name="sex")
private String sex;
public CustomerDAO()
indirizzo=new Address();
name=new CustomerNaming();
public CustomerNaming getNome()
return name;
public void setNome(CustomerNaming nome)
this.name = nome;
public Address getIndirizzo()
return indirizzo;
public void setIndirizzo(Address indirizzo)
this.indirizzo = indirizzo;
public String getEmail()
return email;
public void setEmail(String email)
this.email = email;
public boolean isMailinglist()
return mailinglist;
public void setMailinglist(boolean mailinglist)
this.mailinglist = mailinglist;
public String getSex()
return sex;
public void setSex(String sex)
this.sex = sex;
@Override
public String toString()
return "Customer : [nome=" + name.getNome()
+ ", cognome=" + name.getCognome() + ", indirizzo=" + indirizzo
+ ", email=" + email + ", mailinglist=" + mailinglist
+ ", sex=" + sex + "]";
客户命名.java
@Embeddable
public class CustomerNaming implements Serializable
/**
*
*/
private static final long serialVersionUID = 1L;
@Column (name="nome")
private String nome;
@Column (name="cognome")
private String cognome;
public String getNome()
return nome;
public void setNome(String nome)
this.nome = nome;
public String getCognome()
return cognome;
public void setCognome(String cognome)
this.cognome = cognome;
地址.java
@Entity
@Table(name="indirizzi")
public class Address implements Serializable
/**
*
*/
private static final long serialVersionUID = 1L;
@EmbeddedId
private AddressKey key;
@Column (name="cap")
private String cap;
//private ArrayList<State> state=new ArrayList<State>();
public Address()
key=new AddressKey();
public AddressKey getKey()
return key;
public void setKey(AddressKey key)
this.key = key;
public String getCap()
return cap;
public void setCap(String cap)
this.cap = cap;
AddressKey.java
@Embeddable
public class AddressKey implements Serializable
/**
*
*/
private static final long serialVersionUID = 1L;
@Column(name="via", nullable=false)
private String via;
@Column (name="city", nullable=false)
private String city;
@Column (name="state", nullable=false)
private String state;
public String getState()
return state;
public void setState(String state)
this.state = state;
public String getVia()
return via;
public void setVia(String via)
this.via = via;
public String getCity()
return city;
public void setCity(String city)
this.city = city;
如你所见,我有(试试这个……我还在学习休眠……) 在地址中创建复合 PK,由 AddressKey 映射
所以我必须创建一个复合连接来进行搜索,但没有成功
这是我最后一次(不是最好的......哈哈)尝试......
Query q=s.createQuery("FROM CustomerDAO cust JOIN (cust.indirizzo.key.via cust.indirizzo.key.city , cust.indirizzo.key.state) as indirizzo WHERE cust.name.nome=:nome and cust.name.cognome like :cognome and cust.indirizzo.key.via like :via and cust.indirizzo.key.city like :city and cust.indirizzo.cap like :cap and cust.indirizzo.key.state like :state and cust.sex like :sex and c.email like :mail and cust.mailinglist like :mailinglist")
.setString("nome","\'%"+c.getNome().getNome()+"%\'")
.setString("cognome", c.getNome().getCognome())
.setString("via", c.getIndirizzo().getKey().getVia())
.setString("city", c.getIndirizzo().getKey().getCity())
.setString("cap", c.getIndirizzo().getCap())
.setString("state", c.getIndirizzo().getKey().getState())
.setString("sex", c.getSex())
.setString("mail",c.getEmail());
if(q!=null)
customers=(List<Object[]>)q.list();
在某些情况下,我从 createQuery 收到了一个空查询...
在这种情况下......它根本无法识别查询
org.hibernate.hql.ast.QuerySyntaxException: unexpected token: ( near line 1, column 43 [FROM myapp.customer.CustomerDAO cust JOIN (cust.indirizzo.key.via cust.indirizzo.key.city , cust.indirizzo.key.state) as indirizzo WHERE cust.name.nome=:nome and cust.name.cognome like :cognome and cust.indirizzo.key.via like :via and cust.indirizzo.key.city like :city and cust.indirizzo.cap like :cap and cust.indirizzo.key.state like :state and cust.sex like :sex and c.email like :mail and cust.mailinglist like :mailinglist]
请注意,如下所示的更简单的搜索可以完美地工作...
List<CustomerDAO> customers=(List<CustomerDAO>)(s.createQuery("from CustomerDAO where nome=:nome and cognome=:cognome").setString("nome", nome).setString("cognome", cognome)).list();
感谢您的帮助
问候 翁贝托
【问题讨论】:
【参考方案1】:好的
实际上要简单得多
查询必须没有任何“加入”添加并且有效...
下面的例子
Query q=s.createQuery("FROM CustomerDAO cust WHERE cust.name.nome like :nome ");
感谢您的帮助!
问候
翁贝托
【讨论】:
以上是关于Hibernate HQL Join 与复合键的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate 在 JoinTable (List<>) 中声明复合主键
为啥得到 org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join!加入 3 个表时