当前位置: 首页 > 面试题库 >

JPA 2和Hibernate 3.5.1成员查询不起作用

诸葛康胜
2023-03-14
问题内容

我正在尝试以下JPQL,但它失败了:

Query query = em.createQuery("SELECT u FROM User u WHERE 'admin' MEMBER OF u.roles");
List users = query.query.getResultList();

我得到以下异常:

ERROR [main] PARSER.error(454) | <AST>:0:0: unexpected end of subtree
java.lang.IllegalArgumentException: org.hibernate.hql.ast.QuerySyntaxException: unexpected end of subtree [SELECT u FROM com.online.data.User u WHERE 'admin' MEMBER OF u.roles] ERROR [main] PARSER.error(454) | <AST>:0:0: expecting "from", found '<ASTNULL>'
...
...
Caused by: org.hibernate.hql.ast.QuerySyntaxException: unexpected end of subtree [SELECT u FROM com.online.data.User u WHERE 'admin' MEMBER OF u.roles]

我有Spring 3.0.1.RELEASE,Hibernate 3.5.1-Final和Maven来粘合依赖项。

用户类别:

@Entity
public class User {
  @Id
  @Column(name = "USER_ID")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;
  @Column(unique = true, nullable = false)
  private String username;

  private boolean enabled;

  @ElementCollection
  private Set<String> roles = new HashSet<String>();

...
}

spring配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/tx/spring-context-3.0.xsd
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

 <!-- Reading annotation driven configuration -->
 <tx:annotation-driven transaction-manager="transactionManager" />

 <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
 <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="${jdbc.driverClassName}" />
  <property name="url" value="${jdbc.url}" />
  <property name="username" value="${jdbc.username}" />
  <property name="password" value="${jdbc.password}" />
  <property name="maxActive" value="100" />
  <property name="maxWait" value="1000" />
  <property name="poolPreparedStatements" value="true" />
  <property name="defaultAutoCommit" value="true" />
 </bean>

 <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  <property name="entityManagerFactory" ref="entityManagerFactory" />
  <property name="dataSource" ref="dataSource" />
 </bean>

 <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="jpaVendorAdapter">
   <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="showSql" value="true" />
    <property name="databasePlatform" value="${hibernate.dialect}" />
   </bean>
  </property>
  <property name="loadTimeWeaver">
   <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
  </property>
  <property name="jpaProperties">
   <props>
    <prop key="hibernate.hbm2ddl.auto">update</prop>
    <prop key="hibernate.current_session_context_class">thread</prop>
    <prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
    <prop key="hibernate.show_sql">true</prop>
    <prop key="hibernate.format_sql">false</prop>
    <prop key="hibernate.show_comments">true</prop>
   </props>
  </property>
  <property name="persistenceUnitName" value="punit" />
 </bean>

 <bean id="JpaTemplate" class="org.springframework.orm.jpa.JpaTemplate">
  <property name="entityManagerFactory" ref="entityManagerFactory" />
 </bean>



</beans>

Persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence">

 <persistence-unit name="punit" transaction-type="RESOURCE_LOCAL" />

</persistence>

pom.xml Maven依赖项。

  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate</artifactId>
   <version>${hibernate.version}</version>
   <type>pom</type>
  </dependency>
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>${hibernate.version}</version>
  </dependency>
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-annotations</artifactId>
   <version>${hibernate.version}</version>
  </dependency>
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-entitymanager</artifactId>
   <version>${hibernate.version}</version>
  </dependency>
  <dependency>
   <groupId>commons-dbcp</groupId>
   <artifactId>commons-dbcp</artifactId>
   <version>1.2.2</version>
   <type>jar</type>
  </dependency>
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-web</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-config</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-taglibs</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-acl</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>javax.annotation</groupId>
   <artifactId>jsr250-api</artifactId>
   <version>1.0</version>
  </dependency>
 <properties>
  <!-- Application settings -->
  <spring.version>3.0.1.RELEASE</spring.version>
  <hibernate.version>3.5.1-Final</hibernate.version>

我正在运行单元测试以检查配置,并且我能够运行其他JPQL查询,但我无法运行的唯一条件是IS EMPTY,MEMBER OF条件。

完整的单元测试如下:

测试整合

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations =  { "/spring/dataLayer.xml"})
@Transactional
@TransactionConfiguration
public class TestUserDaoImplIntegration {
  @PersistenceContext
  private EntityManager em;

  @Test
  public void shouldTest() throws Exception {
    try {
//WORKS
Query query = em.createQuery("SELECT u FROM User u WHERE 'admin' in elements(u.roles)"); 
List users = query.query.getResultList();
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    }
    try {
//DOES NOT WORK
Query query = em.createQuery("SELECT u FROM User u WHERE 'admin' MEMBER OF u.roles"); 
List users = query.query.getResultList();
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    }
  }
}

问题答案:

您的查询对我来说 很好 。作为记录,这是JPA 2.0规范关于MEMBER OF操作符的内容:

4.6.13集合成员表达式

> `MEMBER OF`在collection_member_expression中使用比较运算符的语法如下:
>  
>  
>        collection_member_expression ::=
>                 entity_or_value_expression [NOT] MEMBER [OF]
> collection_valued_path_expression
>        entity_or_value_expression ::=
>                 single_valued_object_path_expression |
>                 state_field_path_expression |
>                 simple_entity_or_value_expression
>        simple_entity_or_value_expression ::=
>                 identification_variable |
>                 input_parameter |
>                 literal

此表达式测试指定的值是否是由集合值的路径表达式指定的集合的成员。

集合成员表达式中不支持评估为可嵌入类型的表达式。在本规范的将来版本中,可能会添加对在集合成员表达式中使用可嵌入对象的支持。

如果集合值的路径表达式指定一个空集合,则MEMBER OF表达式FALSE的值为,而NOT MEMBER OF表达式的值为
TRUE。否则,如果集合成员表达式中的collection_valued_pa​​th_expression或Entity_or_value_expression的值为NULL或未知,则集合成员表达式的值为未知。

例:

>     SELECT p
>     FROM Person p
>     WHERE 'Joe' MEMBER OF p.nicknames

因此,由于在查询中看不到任何错误,因此我已经使用EclipseLink 1测试了您的代码,以下代码段也可以正常工作:

Query query = em.createQuery("SELECT u FROM User u WHERE 'admin' MEMBER OF u.roles");
List list = query.getResultList();

但是,使用Hibernate EntityManager
3.5.1-Final确实失败。这听起来像个错误,请随时提出有关Jira的问题。

1为了以防万一,我使用了以下Maven配置文件(用于JPA提供程序):

  <profile>
    <id>eclipselink</id>
    <repositories>
      <repository>
        <id>eclipselink</id>
        <url>http://www.eclipse.org/downloads/download.php?r=1&amp;nf=1&amp;file=/rt/eclipselink/maven.repo/</url>
      </repository>
    </repositories>
    <dependencies>
      <!-- See http://wiki.eclipse.org/EclipseLink/Maven -->
      <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.0.0</version>
      </dependency>
      <!-- optional - only needed if you are using JPA outside of a Java EE container-->
      <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>javax.persistence</artifactId>
        <version>2.0.0</version>
        <scope>provided</scope>
      </dependency>              
    </dependencies>
  </profile>

这是我的persistence.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence
        xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
        version="2.0">

      <persistence-unit name="TestPu" transaction-type="RESOURCE_LOCAL">    
        <class>com.stackoverflow.q2688144.User</class>    
        <properties>
          <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
          <property name="javax.persistence.jdbc.url" value="jdbc:derby:testdb;create=true"/>    
          <property name="eclipselink.target-database" value="DERBY"/>
          <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
        </properties>
      </persistence-unit>
    </persistence>

更新:
在HHH-5209中报告



 类似资料:
  • 你能帮我解决这个问题吗?我想使用此方法在我的数据库中查找特定的缺口(它是由Apache Derby制作的)。我使用了EntityManager并从NetBeans中的数据库中映射持久性-实体类。 我得到这个错误: Java . lang . illegalargumentexception:在EntityManager中创建查询时出现异常:< br >异常描述:解析[SELECT * FROM U

  • 问题内容: 我有一个非常简单的查询,像这样: 我的默认设置是或某些用户ID,但是由于某种原因,该查询总是返回0行,我也尝试过,但还是没有运气,这可能是什么错误? EDTI 因此,在运行更多查询后,我发现我的问题是字段的默认值,因此我修改了查询,现在可以正常使用: 问题答案: NULL值需要特殊处理:http : //dev.mysql.com/doc/refman/5.1/en/working-w

  • 问题内容: 非常感谢你的帮助。我有一个和表。位置 我对位置模型执行以下查询。 然后,我要对其执行附加查询并根据以下内容对其进行过滤 该查询并 没有 工作。它返回一个空对象。 这是参数: location_params 1} permitted: true> ads_params 1} permitted: true> 不允许这样输入特定的列: 我有postgresql,我没有考虑过使用SQL,但是

  • 我想让ElasticSearch在我的盒子上工作。我有以下映射: 所以我有一个“运动鞋”索引,它有一个“运动鞋”类型,一个“品牌”属性,它有一个“ID”和一个“标题”。 检查运动鞋是否存在,运行curl-xget“http://localhost:9200/sneakers/sneaker/1?prettley”,我得到: 现在,runningcurl-xget'http://localhost:

  • 问题内容: 我正在使用嵌套集模型在iPhone上的本地SQLite数据库中存储较大的数据层次结构。我从他们的网站上阅读了MySQL技术文章,了解如何执行此操作,但是他们建议的查询(以及我需要的查询)之一似乎不适用于SQLite,并且我不确定如何解决它。 SQLite报告不是列,我认为这是因为其子查询实现不完整。有人对如何解决此限制有任何想法吗? 查询的目的是获取给定父节点的所有直接子代。 问题答案

  • 问题内容: 我有一个单元格,其中包含用双管道分隔的值。我正在尝试使用以下内容搜索此单元格的内容,(其中10是要搜索的数字)%10、10%,%10%和10 我的查询似乎只返回10。没有其他变化。有人可以告诉我为什么它不起作用吗? 提前谢谢了。(您在下面看到的SQL查询是从准备好的PDO查询语句中导出的内容) 问题答案: 我认为您应该使用LIKE而不是=: