在使用hibernate和jpa的spring mvc应用程序中,我在WordKey
实体和Concept
实体之间存在多对多的关系。 WordKey
有一个concepts
集合,而Concept
有一个wordkeys
集合。我不想使用fetchType=EAGER
,因为性能是一个问题。相反,一旦用户选择了WordKey
,我想用查询的结果填充Collection<Concept>
,查询的结果为selectedKeyWord
wk
作为参数,并返回底层数据库中与WordKey
关联的集合concepts
。我如何在JPQL中编写此查询?休眠没有定位多对多查询中的联结表
这是我到目前为止的查询。它不工作(请参阅下面的错误):
@SuppressWarnings("unchecked")
public Collection<Concept> findConceptsForKeyWord(ConcWordKey wk) {
Query query = this.em.createQuery(
"SELECT DISTINCT concept FROM Concept concept join concept.wordkeys k WHERE k.name =:wk"
);
query.setParameter("wk", wk.getName());
Collection<Concept> result = (Collection<Concept>) query.getResultList();
return result;
}
这是上述代码生成的hibernate查询。需要注意的是它正在寻找一个假想concept_wordkey
表,而不是使用wordkey_junction
加入,其在下文中进一步所述WordKey
实体代码指定的表的:
select distinct conc0_.effectiveTime as effectiv1_52_,
conc0_.id as id2_52_,
from concept conc0_
inner join concept_wordkey wordkeys1_
on conc0_.effectiveTime=wordkeys1_.concept_effectiveTime
and conc0_.id=wordkeys1_.concept_id
inner join wordkey conc2_
on wordkeys1_.wordkeys_keyword=conc2_.keyword
where conc2_.keyword=?
在堆栈跟踪正在生成特定的错误是:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
Table 'mydb.concept_wordkey' doesn't exist
这里是Concept
实体:
@Entity
@Table(name = "concept")
public class Concept implements Serializable{
@EmbeddedId
public EmbedPK conceptPk;
@ManyToMany(cascade={CascadeType.ALL})
private Set<WordKey> wordkeys;
public EmbedPK getConceptPk(){return conceptPk;}
protected Set<WordKey> getWordkeysInternal() {
if (this.wordkeys == null) {this.wordkeys = new HashSet<WordKey>();}
return this.wordkeys;
}
public List<WordKey> getWordkeys() {
List<WordKey> sortedWordkeys = new ArrayList<WordKey>(getWordkeysInternal());
PropertyComparator.sort(sortedWordkeys, new MutableSortDefinition("wordkey", true, true));
return Collections.unmodifiableList(sortedWordkeys);
}
public WordKey getWordkey(String s) {return getWordkey(s, false);}
public WordKey getWordkey(String ps, boolean ignoreNew) {
ps = ps.toLowerCase();
for (WordKey s1 : getWordkeysInternal()) {
if (!ignoreNew || !s1.isNew()) {
String keyword = s1.getName();
keyword = keyword.toLowerCase();
if (keyword.equals(ps)) {return s1;}
}
}
return null;
}
}
这里是WordKey
实体:
@Entity
@Table(name = "wordkey")
public class WordKey {
@Id
@Column(name="keyword")
private String name;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="wordkey_junction",
joinColumns={@JoinColumn(name="keyword")},
inverseJoinColumns={@JoinColumn(name="conceptid"),@JoinColumn(name="effectiveTime")})
private Set<Concept> concepts = new HashSet<Concept>();
public String getName(){return name;}
public void setName(String nm){name=nm;}
protected Set<Concept> getConceptsInternal() {
if (this.concepts == null) {this.concepts = new HashSet<Concept>();}
return this.concepts;
}
public List<Concept> getConcepts() {
List<Concept> sortedConcepts = new ArrayList<Concept>(getConceptsInternal());
PropertyComparator.sort(sortedConcepts, new MutableSortDefinition("conceptid", true, true));
return Collections.unmodifiableList(sortedConcepts);
}
public Concept getConcept(BigInteger s) {return getConcept(s, false);}
public Concept getConcept(BigInteger ps, boolean ignoreNew) {
for (Concept s1 : getConceptsInternal()) {
if (!ignoreNew || !s1.isNew()) {
BigInteger compName = s1.getConceptPk().getId();
if (compName == ps) {return s1;}
}
}
return null;
}
}