JPA 2 und Hibernate 3.5.1 MITGLIED DER query funktioniert nicht
Ich versuche die folgende JPQL schlägt fehl, misserably:
Query query = em.createQuery("SELECT u FROM User u WHERE 'admin' MEMBER OF u.roles");
List users = query.query.getResultList();
Bekomme ich die folgende exception:
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]
Ich Spring 3.0.1.RELEASE, Hibernate 3.5.1-Finale und maven zu kleben Abhängigkeiten.
User-Klasse:
@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-Konfiguration:
<?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 Abhängigkeiten.
<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>
Im Betrieb ein unit-test zum prüfen der Konfiguration und ich bin in der Lage zu laufen, andere JPQL-Abfragen die einzigen, die ich nicht in der Lage bin zu laufen, sind die LEER, MITGLIED VON Bedingungen.
Die komplette unit-test ist wie folgt:
TestIntegration
@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;
}
}
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre Abfrage sieht völlig in Ordnung zu mir. Für das Protokoll, dies ist, was die JPA-2.0-Spezifikation schreibt über die
MEMBER OF
Betreiber:So, denn ich kann nicht sehen, nichts falsch in Ihre Abfrage, die ich getestet habe deinen code mit EclipseLink1 und das folgende snippet funktioniert einfach:
Scheitert aber in der Tat mit Hibernate EntityManager 3.5.1-Finale. Das klingt wie ein bug, fühlen Sie sich frei zu erheben ein Jira-issue.
1 Nur für den Fall, ich habe folgende Maven-Profil (für den JPA-provider):
Und das ist mein
persistence.xml
:Update: berichtet in HHH-5209
Hibernate Bug #HHH-5209,
als workaround verwenden Sie die folgende syntax:
Ihre Abfrage ist absolut richtig und sollte funktionieren. Ich lief in das gleiche problem nur heute und Dank diesem post, war in der Lage zu stoppen, schlug meinen Kopf gegen die Wand.
Da @ElementCollection ist wirklich eine schöne Verknüpfung zu einem verknüpften element mit einer inneren Vereinigung, können Sie immer noch verwenden von join-Semantik in Ihrer Abfrage.
Zu setzen, dass in bessere Bedingungen, müssen Sie beitreten Ihre Sammlung, und legen Sie eine Bedingung in der where.
Zu legen, die in etwas mehr Beton...
Ihre Abfrage:
Kann geschrieben werden als:
Hoffe, das hilft!
Ich denke
member of
kann nicht verwendet werden, mit einem@ElementCollection
Eigenschaft.MEMBER OF
soll die Arbeit an der Sammlung (und es tut), unabhängig von der annotation verwendet.