【发布时间】:2014-05-15 23:20:57
【问题描述】:
在使用 hibernate 和 jpa 的 spring mvc 应用程序中,WordKey 实体和 Concept 实体之间存在多对多关系。 WordKey 有一个 concepts 集合,Concept 有一个 wordkeys 集合。我不想使用fetchType=EAGER,因为性能是个问题。相反,一旦用户选择了WordKey,我想使用以selectedKeyWordwk 作为参数并返回关联的concepts 的集合的查询结果填充Collection<Concept>在底层数据库中使用WordKey。如何在 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;
}
这是上面代码生成的休眠查询。请注意,它正在寻找一个虚构的concept_wordkey 表,而不是使用在下面的WordKey 实体代码中指定的wordkey_junction 连接表:
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;
}
}
【问题讨论】:
标签: java sql spring hibernate jpa