我试图配置QueryDSL + Spring JPA + Hibernate。 QueryDSL' Q'使用Maven POM配置生成我的域对象的查询类。我有一个' Person'具有String属性' username'的对象。我想要一个用username =" jon"返回的人。当我通过将用户名分配为" jon"来运行简单的应用程序时我收到以下错误:
Caused by: java.lang.IllegalArgumentException: Parameter value [person.username = jon] was not matching type [java.lang.String]
at org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:360)
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:364)
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:317)
at org.hibernate.ejb.criteria.CriteriaQueryCompiler$3.setParameter(CriteriaQueryCompiler.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:362)
at com.sun.proxy.$Proxy61.setParameter(Unknown Source)
at org.springframework.data.jpa.repository.query.CriteriaQueryParameterBinder.bind(CriteriaQueryParameterBinder.java:73)
at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:111)
at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:172)
at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:163)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.invokeBinding(PartTreeJpaQuery.java:207)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:134)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.doCreateQuery(PartTreeJpaQuery.java:74)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:164)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:202)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:74)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:97)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:88)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:395)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:373)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$DefaultMethodInvokingMethodInterceptor.invoke(RepositoryFactorySupport.java:486)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 49 more
有人可以协助吗?相关的课程+文件如下。
我的人类:
package com.motodoc.hub.domain;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
@Entity
@Table(name="persons")
public class Person implements UserDetails {
@Id
@Column(name="PRS_ID")
private int id;
@Column(name="PRS_USERNAME")
private String username;
@Column(name="PRS_PASSWORD")
private String password;
@Column(name="PRS_FIRST_NAME")
private String firstName;
@Column(name="PRS_MIDDLE_NAME")
private String middleName;
@Column(name="PRS_LAST_NAME")
private String lastName;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "USER_ROLES", joinColumns = {
@JoinColumn(name = "USR_PRS_ID") }, inverseJoinColumns = {
@JoinColumn(name = "RLE_ID") })
private Set<SecurityRole> roles;
@Transient
private final String PERMISSION_PREFIX = "ROLE_PERM_";
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthorityImpl> authorities = new HashSet<GrantedAuthorityImpl>();
for (SecurityRole role : roles) {
for (SecurityPermission permission : role.getPermissions()) {
GrantedAuthorityImpl authority = new GrantedAuthorityImpl(PERMISSION_PREFIX + permission.getPermission());
authorities.add(authority);
}
}
return authorities;
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return true;
}
public String getPERMISSION_PREFIX() {
return PERMISSION_PREFIX;
}
public Set<SecurityRole> getRoles() {
return roles;
}
public void setRoles(Set<SecurityRole> roles) {
this.roles = roles;
}
}
QueryDSL生成QPerson类:
package com.motodoc.hub.domain;
import static com.mysema.query.types.PathMetadataFactory.*;
import com.mysema.query.types.path.*;
import com.mysema.query.types.PathMetadata;
import javax.annotation.Generated;
import com.mysema.query.types.Path;
import com.mysema.query.types.path.PathInits;
/**
* QPerson is a Querydsl query type for Person
*/
@Generated("com.mysema.query.codegen.EntitySerializer")
public class QPerson extends EntityPathBase<Person> {
private static final long serialVersionUID = -1472547386;
public static final QPerson person = new QPerson("person");
public final StringPath firstName = createString("firstName");
public final NumberPath<Integer> id = createNumber("id", Integer.class);
public final StringPath lastName = createString("lastName");
public final StringPath middleName = createString("middleName");
public final StringPath password = createString("password");
public final SetPath<SecurityRole, QSecurityRole> roles = this.<SecurityRole, QSecurityRole>createSet("roles", SecurityRole.class, QSecurityRole.class, PathInits.DIRECT2);
public final StringPath username = createString("username");
public QPerson(String variable) {
super(Person.class, forVariable(variable));
}
public QPerson(Path<? extends Person> path) {
super(path.getType(), path.getMetadata());
}
public QPerson(PathMetadata<?> metadata) {
super(Person.class, metadata);
}
}
服务类:
package com.motodoc.hub.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.motodoc.hub.domain.Person;
import com.motodoc.hub.domain.QPerson;
import com.motodoc.hub.repository.IPersonDao;
import com.mysema.query.types.Predicate;
public class SecurityUserServiceImpl implements ISecurityUserService {
@Autowired
private IPersonDao personDao;
@Override
public Person findByUsername(String username) {
QPerson query = QPerson.person;
Predicate predicate = query.username.eq(username);
return personDao.findByUsername(predicate);
}
@Override
public List<Person> findAll() {
return personDao.findAll();
}
}
存储库类:
package com.motodoc.hub.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import com.motodoc.hub.domain.Person;
import com.mysema.query.types.Predicate;
public interface IPersonDao extends JpaRepository<Person, Long>, QueryDslPredicateExecutor<Person> {
public Person findByUsername(Predicate predicate);
}
POM文件:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.motodoc</groupId>
<artifactId>com.motodoc</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>hub</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.core.version>4.1.5.RELEASE</spring.core.version>
<spring.data.jpa.version>1.7.2.RELEASE</spring.data.jpa.version>
<spring.security.version>3.2.5.RELEASE</spring.security.version>
<cglib.version>2.2</cglib.version>
<aspectj.version>1.6.10</aspectj.version>
<mysql.connector.version>5.1.16</mysql.connector.version>
<hibernate.entitymanager.version>3.6.3.Final</hibernate.entitymanager.version>
<hibernate.jpa-api.version>2.0-cr-1</hibernate.jpa-api.version>
<c3p0.version>0.9.1.2</c3p0.version>
<thymeleaf.version>2.1.4.RELEASE</thymeleaf.version>
<querydsl.version>3.2.4</querydsl.version>
<slf4j.version>1.6.1</slf4j.version>
<log4j.version>1.2.14</log4j.version>
<javax.servlet-api.version>3.0.1</javax.servlet-api.version>
<javax.jstl-taglibs.version>1.1.2</javax.jstl-taglibs.version>
<jackson.version>1.9.3</jackson.version>
<!-- Testing -->
<mockito.version>1.8.5</mockito.version>
<junit.version>4.8.2</junit.version>
<!-- Plugins -->
<tomcat7.maven.plugin.version>2.0</tomcat7.maven.plugin.version>
<jetty.maven.plugin.version>8.1.5.v20120716</jetty.maven.plugin.version>
<maven.copy.plugin.version>0.2.3</maven.copy.plugin.version>
<maven.compiler.plugin.version>2.3.2</maven.compiler.plugin.version>
<maven.apt.plugin.version>1.1.3</maven.apt.plugin.version>
</properties>
<dependencies>
<!-- Spring Core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.core.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.core.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.core.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.core.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.core.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.core.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.core.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<!-- A seamless aspect-oriented extension to the Java programming language -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!-- Cglib is a powerful, high performance and quality Code Generation Library,
It is used to extend JAVA classes and implements interfaces at runtime. -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>${cglib.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- The JavaServer Pages Standard Tag Library (JSTL) encapsulates, as simple tags, core
functionality common to many JSP applications. -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${javax.jstl-taglibs.version}</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>${javax.jstl-taglibs.version}</version>
</dependency>
<!-- Data Mapper package is a high-performance data binding package built
on Jackson JSON processor -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Jackson is a high-performance JSON processor (parser, generator) -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>${jackson.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Logger -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- The Simple Logging Facade for Java or (SLF4J) serves as a simple facade or abstraction
for various logging frameworks, e.g. java.util.logging, log4j and logback, allowing the end
user to plug in the desired logging framework at deployment time. -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Spring Data JPA -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${spring.data.jpa.version}</version>
</dependency>
<!-- Thymeleaf -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>${thymeleaf.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>${thymeleaf.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity3</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<!-- Database pooling -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>${c3p0.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Hibernate and JPA -->
<dependency>
<groupId>org.hibernate.java-persistence</groupId>
<artifactId>jpa-api</artifactId>
<version>${hibernate.jpa-api.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.entitymanager.version}</version>
<scope>compile</scope>
</dependency>
<!-- QueryDSL -->
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-core</artifactId>
<version>${querydsl.version}</version>
<!-- <type>jar</type>
<scope>compile</scope> -->
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
<!-- <type>jar</type>
<scope>compile</scope> -->
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<!-- <scope>provided</scope> -->
</dependency>
<!-- Javax Servlet. This needs to be included for runtime only! -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- Testing dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<type>jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>${mockito.version}</version>
<type>jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.core.version}</version>
<type>jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>hub</finalName>
<plugins>
<!-- Tomcat 7 plugin -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>${tomcat7.maven.plugin.version}</version>
<configuration>
<port>8080</port>
</configuration>
</plugin>
<!-- Jetty 8 plugin -->
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.maven.plugin.version}</version>
<configuration>
<webApp>
<contextPath>/spring-thymeleaf-tutorial</contextPath>
</webApp>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.0.9</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>src/main/generated</outputDirectory>
<!-- <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor> -->
<processor>com.mysema.query.apt.hibernate.HibernateAnnotationProcessor</processor>
<options>
<querydsl.entityAccessors>true</querydsl.entityAccessors>
</options>
</configuration>
</execution>
</executions>
</plugin>
<!-- The Resources Plugin handles the copying of project resources to the
output directory. @see http://maven.apache.org/plugins/maven-resources-plugin/index.html -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-meta-inf</id>
<phase>compile</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}/META-INF</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/java/META-INF</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>bootstrap</id>
<repositories>
<!-- For developing against latest Spring milestones -->
<repository>
<id>org.springframework.maven.milestone</id>
<name>Spring Maven Milestone Repository</name>
<url>http://maven.springframework.org/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>full-bootstrap</id>
<repositories>
<!-- For main Spring releases -->
<repository>
<id>org.springframework.maven.release</id>
<name>Spring Maven Release Repository</name>
<url>http://maven.springframework.org/release</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<!-- For testing against latest Spring snapshots -->
<repository>
<id>org.springframework.maven.snapshot</id>
<name>Spring Maven Snapshot Repository</name>
<url>http://maven.springframework.org/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<!-- For developing against latest Spring milestones -->
<repository>
<id>org.springframework.maven.milestone</id>
<name>Spring Maven Milestone Repository</name>
<url>http://maven.springframework.org/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<!-- JBoss repository -->
<repository>
<id>jboss</id>
<name>JBoss repository</name>
<url>https://repository.jboss.org/nexus/content/repositories/releases</url>
</repository>
</repositories>
</profile>
</profiles>
</project>
答案 0 :(得分:3)
只需将用户名传递给存储库方法
,而不是传递谓词findByUsername(String username);
当你有findBySomething
时,Spring会在你的实体中寻找一个名为something
的属性,显然传递的参数必须与something
的类型相匹配。
如果您确实希望将它与谓词一起使用,则可以将谓词传递给内置方法,例如findOne()
,findAll()
或count()
。所以你的服务可能看起来像
@Override
public Person findByUsername(String username) {
QPerson query = QPerson.person;
Predicate predicate = query.username.eq(username);
return personDao.findOne(predicate);
}