使用复合键 (EJB) 的命名查询

Posted

技术标签:

【中文标题】使用复合键 (EJB) 的命名查询【英文标题】:Named query with composite key (EJB) 【发布时间】:2013-03-13 10:06:52 【问题描述】:

我有一个带有复合键的关联表。我正在尝试运行基于某些值(复合键)进行选择的命名查询。

这就是代码的样子:

@Entity
@NamedQueries(
@NamedQuery(name = "MW.findAll", query = "SELECT mw FROM MemberWorkout mw"),
@NamedQuery(name = "MW.find1", query = "SELECT mw FROM MemberWorkout mw WHERE mw.SocialSecurity LIKE :SocialSecurity"), )
@Table(name = "MemberWorkout")
public class MemberWorkout implements Serializable 

private Member member;
private Workout workout;
private String date;
private MWId mwId;

@EmbeddedId
public MWId getId() 
    return mwId;


public void setId(MWId mwId) 
    this.mwId = mwId;

....
@ManyToOne
@JoinColumn(name = "SocialSecurity", insertable = false, updatable = false)
public Member getMember() 
    return member;


public void setMember(Member member) 
    this.member = member;

这是我在部署它并启动服务器 (JBOSS) 时遇到的第一个错误:

ERROR [org.hibernate.internal.SessionFactoryImpl] (MSC service thread 1-1) HHH000177:   Error in named query: MW.find1: org.hibernate.QueryException: could not resolve property: SocialSecurity of: org.ics.ejb.MemberWorkout [SELECT mw FROM org.ics.ejb.MemberWorkout mw WHERE mw.SocialSecurity LIKE :SocialSecurity]
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:83) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:77) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1809) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.ast.tree.FromElementType.getPropertyType(FromElementType.java:313) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.ast.tree.FromElement.getPropertyType(FromElement.java:485) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.ast.tree.DotNode.getDataType(DotNode.java:598) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.ast.tree.DotNode.prepareLhs(DotNode.java:266) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.ast.tree.DotNode.resolve(DotNode.java:213) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:118) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:114) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:883) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1246) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4252) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:3874) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:1923) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:782) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:583) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:287) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:235) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:248) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:183) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:101) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:119) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.internal.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:974) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:485) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1737) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:84) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:904) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:889) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.createContainerEntityManagerFactory(PersistenceUnitServiceImpl.java:162) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.start(PersistenceUnitServiceImpl.java:85) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [rt.jar:1.7.0_11]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [rt.jar:1.7.0_11]
at java.lang.Thread.run(Unknown Source) [rt.jar:1.7.0_11]

【问题讨论】:

您的实体似乎没有名为 SocialSecurity 的字段或适当的 getter。该错误是意料之中的。 如果字段名称 SocialSecurity 是复合键的一部分,我该如何拥有它? 【参考方案1】:

如果我正确理解了这个问题,SocialSecurityMWId 可嵌入的字段。如果您想通过查询访问它,则需要通过嵌入的 Id 导航到它,如下所示:

SELECT mw FROM MemberWorkout mw WHERE mw.id.SocialSecurity...

我假设属性名称是大写的,就像在您的代码中一样。如果不是,请将其替换为正确的名称。

请注意,您使用的是属性访问,这意味着由于访问器方法被注释,您需要根据JavaBean标准在查询中命名属性(getId()表示HQL和JPQL将访问preperty为@ 987654325@)。如果您对该字段进行注释,则需要将查询更改为mwId

【讨论】:

非常感谢!我犯的许多错误之一是尝试 mw.getId... 不知道省略“get”并将第一个字母小写(即“id”)。其次,我尝试使用表的实际名称(在 SQL 中)而不是属性名称来访问我的属性。

以上是关于使用复合键 (EJB) 的命名查询的主要内容,如果未能解决你的问题,请参考以下文章

如果顶点是在 scala gremline 中使用复合键创建的,如何使用 vertexId 进行查询

Spring Data Cassandra:如何使用复合键查询表?

EntityFramework - 包含复合键的查询

具有三个键的复合索引,如果我查询跳过中间一个会发​​生啥?

Cassandra Spring Data不允许我直接通过复合主键查询数据

ejb3:用简单的主键映射多对多关系