Spring 4 - 配置 XML jpa:repositories 抛出 NoSuchMethodError BeanDefinitionParserDelegate.getEnvironment()
Spring 4 - Config XML jpa:repositories throwing NoSuchMethodError BeanDefinitionParserDelegate.getEnvironment()
我正在尝试将 Gradle 项目 here 集成到我的 Maven 项目中。文件 data-context.xml 用于使用 Spring 配置 Hibernate 以生成用于验证用户对 RESTful 接口的请求的存储库。
一切正常,但当我尝试部署到 tomcat 服务器时,我看到以下问题:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityContextFilter' defined in file [/var/lib/tomcat6/webapps/services/WEB-INF/classes/com/services/filter/SecurityContextFilter.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.services.user.UserRepository]: : Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.services.user.domain.User com.services.user.UserRepository.findBySession(java.lang.String)!; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.services.user.domain.User com.services.user.UserRepository.findBySession(java.lang.String)!
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1139) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1042) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4210) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4709) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:526) [catalina-6.0.24.jar:na]
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:905) [catalina-6.0.24.jar:na]
at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:740) [catalina-6.0.24.jar:na]
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:500) [catalina-6.0.24.jar:na]
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1277) [catalina-6.0.24.jar:na]
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:321) [catalina-6.0.24.jar:na]
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.StandardHost.start(StandardHost.java:722) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.StandardService.start(StandardService.java:516) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710) [catalina-6.0.24.jar:na]
at org.apache.catalina.startup.Catalina.start(Catalina.java:593) [catalina-6.0.24.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_79]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_79]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_79]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_79]
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) [bootstrap-6.0.24.jar:na]
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) [bootstrap-6.0.24.jar:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.services.user.domain.User com.services.user.UserRepository.findBySession(java.lang.String)!
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
... 39 common frames omitted
Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.services.user.domain.User com.services.user.UserRepository.findBySession(java.lang.String)!
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:92) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:62) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.java:72) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromQueryAnnotation(JpaQueryFactory.java:53) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:136) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:204) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:73) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:347) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:185) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:239) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:225) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
... 50 common frames omitted
Caused by: java.lang.NullPointerException: null
at org.hibernate.internal.util.StringHelper.root(StringHelper.java:345) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.getSubclassPropertyTableNumber(AbstractEntityPersister.java:1994) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:61) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1970) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.tree.FromElement.getIdentityColumns(FromElement.java:355) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.tree.IdentNode.resolveAsAlias(IdentNode.java:167) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.tree.IdentNode.resolve(IdentNode.java:104) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:126) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:121) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:959) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.propertyRef(HqlSqlBaseWalker.java:1146) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExpr(HqlSqlBaseWalker.java:2253) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExprList(HqlSqlBaseWalker.java:2194) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectClause(HqlSqlBaseWalker.java:1476) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:573) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:131) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:93) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:167) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1836) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:328) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_79]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_79]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_79]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_79]
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:344) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at com.sun.proxy.$Proxy50.createQuery(Unknown Source) ~[na:na]
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:86) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
... 63 common frames omitted
我倾向于认为这是由于data-context.xml没有正确初始化导致查询验证失败。下面是我的代码示例,以及我在 pom 中包含的 spring 依赖项。
数据-context.xml-
<?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:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/integration/jdbc
http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/repository
http://www.springframework.org/schema/data/repository/spring-repository.xsd">
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="samplePersistenceUnit"/>
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
</bean>
<jpa:repositories base-package="com.services.user" />
<!--
the above shows the following error in Eclipse :
java.lang.NoSuchMethodError: org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.getEnvironment()
-->
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
</bean>
<tx:annotation-driven/>
...
</beans>
Domain.User class -
@Entity
@Table(name="rest_user")
public class User extends BaseEntity {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private static final int HASH_ITERATIONS = 1000;
private String firstName;
private String lastName;
private String emailAddress;
private String hashedPassword;
private boolean isVerified;
@Enumerated(EnumType.STRING)
private Role role;
@OneToMany(mappedBy="user",
targetEntity=VerificationToken.class,
cascade= CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
private List<VerificationToken> verificationTokens = new ArrayList<VerificationToken>();
@OneToOne(fetch = FetchType.LAZY,
mappedBy = "user",
cascade = CascadeType.ALL)
private AuthorizationToken authorizationToken;
Domain.AuthorizationToken class -
@Entity
@Table(name="rest_authorization_token")
public class AuthorizationToken extends AbstractPersistable<Long> {
private final static Integer DEFAULT_TIME_TO_LIVE_IN_SECONDS = (60 * 60 * 24 * 30); //30 Days
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@Column(length=36)
private String token;
private Date timeCreated;
private Date expirationDate;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "token")
private User user;
UserRepository class -
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmailAddress(String emailAddress);
@Query("select u from User u where uuid = ?")
User findByUuid(String uuid);
@Query("select u from User u where u in (select user from AuthorizationToken where lastUpdated < ?)")
List<User> findByExpiredSession(Date lastUpdated);
@Query("select u from User u where u = (select user from AuthorizationToken where token = ?)")
User findBySession(String token);
}
VerificationToken class -
@Entity
@Table(name = "rest_verification_token")
public class VerificationToken extends BaseEntity {
private static final int DEFAULT_EXPIRY_TIME_IN_MINS = 60 * 24; //24 hours
@Column(length=36)
private String token;
private Date expiryDate;
@Enumerated(EnumType.STRING)
private VerificationTokenType tokenType;
private boolean verified;
@ManyToOne
User user;
public VerificationToken() {
super();
this.token = UUID.randomUUID().toString();
this.expiryDate = calculateExpiryDate(DEFAULT_EXPIRY_TIME_IN_MINS);
}
public VerificationToken(User user, VerificationTokenType tokenType, int expirationTimeInMinutes) {
this();
this.user = user;
this.tokenType = tokenType;
this.expiryDate = calculateExpiryDate(expirationTimeInMinutes);
}
pom.xml Spring 依赖项-(我确定没有冲突)
对于初学者,我建议修复你的实体,你有一个基本的一对一映射,但你正在让它变得复杂,而且你不需要复合主键。接下来你的查询也很复杂你不需要连接你可以简单地 return 来自 AuthorizationToken
.
的 user
字段
实体
您的所有实体都直接或间接扩展 AbstractPersistable
class 已经有一个 id 字段。不需要添加额外的 @Id
并且只会混淆 JPA,因为您现在突然需要一个复合主键。解决方案很容易从实体中删除自定义 id 字段。
@Entity
@Table(name="rest_authorization_token")
public class AuthorizationToken extends AbstractPersistable<Long> {
@Column(length=36)
private String token;
@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
private User user;
}
AuthorizationToken
不可嵌入,因此删除注释。对于一对一映射,添加 @PrimaryKeyJoinColumn
注释。 token
字段不需要是 @Id
AbstractPersistable
中已经有一个主键字段。
在 User
实体上删除 @IdClass
,因为简单映射不需要它。如果您不想要双向关系,请从 User
实体中删除 authorizationToken
字段。如果你想使用它,只需删除 @Id
.
@Entity
@Table(name="rest_user")
public class User extends BaseEntity {
@OneToOne(fetch = FetchType.LAZY,
mappedBy = "user",
cascade = CascadeType.ALL)
private AuthorizationToken authorizationToken;
}
注意:我省略了其余的实体代码,因为它们保持不变。
现在实体已经清理完毕,只需 returning AuthorizationToken
中的 user
字段即可简化查询。
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmailAddress(String emailAddress);
User findByUuid(String uuid);
@Query("select user from AuthorizationToken where lastUpdated < ?")
List<User> findByExpiredSession(Date lastUpdated);
@Query("select user from AuthorizationToken where token = ?")
User findBySession(String token);
}
我还注意到您有 findByUuid
的 @Query
不需要,因为 Spring Data JPA 可以为您生成该查询。
我正在尝试将 Gradle 项目 here 集成到我的 Maven 项目中。文件 data-context.xml 用于使用 Spring 配置 Hibernate 以生成用于验证用户对 RESTful 接口的请求的存储库。
一切正常,但当我尝试部署到 tomcat 服务器时,我看到以下问题:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityContextFilter' defined in file [/var/lib/tomcat6/webapps/services/WEB-INF/classes/com/services/filter/SecurityContextFilter.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.services.user.UserRepository]: : Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.services.user.domain.User com.services.user.UserRepository.findBySession(java.lang.String)!; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.services.user.domain.User com.services.user.UserRepository.findBySession(java.lang.String)!
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1139) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1042) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4210) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4709) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:526) [catalina-6.0.24.jar:na]
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:905) [catalina-6.0.24.jar:na]
at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:740) [catalina-6.0.24.jar:na]
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:500) [catalina-6.0.24.jar:na]
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1277) [catalina-6.0.24.jar:na]
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:321) [catalina-6.0.24.jar:na]
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.StandardHost.start(StandardHost.java:722) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.StandardService.start(StandardService.java:516) [catalina-6.0.24.jar:na]
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710) [catalina-6.0.24.jar:na]
at org.apache.catalina.startup.Catalina.start(Catalina.java:593) [catalina-6.0.24.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_79]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_79]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_79]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_79]
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) [bootstrap-6.0.24.jar:na]
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) [bootstrap-6.0.24.jar:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.services.user.domain.User com.services.user.UserRepository.findBySession(java.lang.String)!
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
... 39 common frames omitted
Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.services.user.domain.User com.services.user.UserRepository.findBySession(java.lang.String)!
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:92) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:62) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.java:72) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromQueryAnnotation(JpaQueryFactory.java:53) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:136) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:204) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:73) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:347) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:185) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:239) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:225) ~[spring-data-commons-1.10.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
... 50 common frames omitted
Caused by: java.lang.NullPointerException: null
at org.hibernate.internal.util.StringHelper.root(StringHelper.java:345) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.getSubclassPropertyTableNumber(AbstractEntityPersister.java:1994) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:61) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1970) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.tree.FromElement.getIdentityColumns(FromElement.java:355) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.tree.IdentNode.resolveAsAlias(IdentNode.java:167) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.tree.IdentNode.resolve(IdentNode.java:104) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:126) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:121) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:959) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.propertyRef(HqlSqlBaseWalker.java:1146) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExpr(HqlSqlBaseWalker.java:2253) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExprList(HqlSqlBaseWalker.java:2194) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectClause(HqlSqlBaseWalker.java:1476) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:573) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:131) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:93) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:167) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1836) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:328) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_79]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_79]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_79]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_79]
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:344) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at com.sun.proxy.$Proxy50.createQuery(Unknown Source) ~[na:na]
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:86) ~[spring-data-jpa-1.8.0.RELEASE.jar:na]
... 63 common frames omitted
我倾向于认为这是由于data-context.xml没有正确初始化导致查询验证失败。下面是我的代码示例,以及我在 pom 中包含的 spring 依赖项。
数据-context.xml-
<?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:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/integration/jdbc
http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/repository
http://www.springframework.org/schema/data/repository/spring-repository.xsd">
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="samplePersistenceUnit"/>
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
</bean>
<jpa:repositories base-package="com.services.user" />
<!--
the above shows the following error in Eclipse :
java.lang.NoSuchMethodError: org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.getEnvironment()
-->
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
</bean>
<tx:annotation-driven/>
...
</beans>
Domain.User class -
@Entity
@Table(name="rest_user")
public class User extends BaseEntity {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private static final int HASH_ITERATIONS = 1000;
private String firstName;
private String lastName;
private String emailAddress;
private String hashedPassword;
private boolean isVerified;
@Enumerated(EnumType.STRING)
private Role role;
@OneToMany(mappedBy="user",
targetEntity=VerificationToken.class,
cascade= CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
private List<VerificationToken> verificationTokens = new ArrayList<VerificationToken>();
@OneToOne(fetch = FetchType.LAZY,
mappedBy = "user",
cascade = CascadeType.ALL)
private AuthorizationToken authorizationToken;
Domain.AuthorizationToken class -
@Entity
@Table(name="rest_authorization_token")
public class AuthorizationToken extends AbstractPersistable<Long> {
private final static Integer DEFAULT_TIME_TO_LIVE_IN_SECONDS = (60 * 60 * 24 * 30); //30 Days
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@Column(length=36)
private String token;
private Date timeCreated;
private Date expirationDate;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "token")
private User user;
UserRepository class -
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmailAddress(String emailAddress);
@Query("select u from User u where uuid = ?")
User findByUuid(String uuid);
@Query("select u from User u where u in (select user from AuthorizationToken where lastUpdated < ?)")
List<User> findByExpiredSession(Date lastUpdated);
@Query("select u from User u where u = (select user from AuthorizationToken where token = ?)")
User findBySession(String token);
}
VerificationToken class -
@Entity
@Table(name = "rest_verification_token")
public class VerificationToken extends BaseEntity {
private static final int DEFAULT_EXPIRY_TIME_IN_MINS = 60 * 24; //24 hours
@Column(length=36)
private String token;
private Date expiryDate;
@Enumerated(EnumType.STRING)
private VerificationTokenType tokenType;
private boolean verified;
@ManyToOne
User user;
public VerificationToken() {
super();
this.token = UUID.randomUUID().toString();
this.expiryDate = calculateExpiryDate(DEFAULT_EXPIRY_TIME_IN_MINS);
}
public VerificationToken(User user, VerificationTokenType tokenType, int expirationTimeInMinutes) {
this();
this.user = user;
this.tokenType = tokenType;
this.expiryDate = calculateExpiryDate(expirationTimeInMinutes);
}
pom.xml Spring 依赖项-(我确定没有冲突)
对于初学者,我建议修复你的实体,你有一个基本的一对一映射,但你正在让它变得复杂,而且你不需要复合主键。接下来你的查询也很复杂你不需要连接你可以简单地 return 来自 AuthorizationToken
.
user
字段
实体
您的所有实体都直接或间接扩展 AbstractPersistable
class 已经有一个 id 字段。不需要添加额外的 @Id
并且只会混淆 JPA,因为您现在突然需要一个复合主键。解决方案很容易从实体中删除自定义 id 字段。
@Entity
@Table(name="rest_authorization_token")
public class AuthorizationToken extends AbstractPersistable<Long> {
@Column(length=36)
private String token;
@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
private User user;
}
AuthorizationToken
不可嵌入,因此删除注释。对于一对一映射,添加 @PrimaryKeyJoinColumn
注释。 token
字段不需要是 @Id
AbstractPersistable
中已经有一个主键字段。
在 User
实体上删除 @IdClass
,因为简单映射不需要它。如果您不想要双向关系,请从 User
实体中删除 authorizationToken
字段。如果你想使用它,只需删除 @Id
.
@Entity
@Table(name="rest_user")
public class User extends BaseEntity {
@OneToOne(fetch = FetchType.LAZY,
mappedBy = "user",
cascade = CascadeType.ALL)
private AuthorizationToken authorizationToken;
}
注意:我省略了其余的实体代码,因为它们保持不变。
现在实体已经清理完毕,只需 returning AuthorizationToken
中的 user
字段即可简化查询。
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmailAddress(String emailAddress);
User findByUuid(String uuid);
@Query("select user from AuthorizationToken where lastUpdated < ?")
List<User> findByExpiredSession(Date lastUpdated);
@Query("select user from AuthorizationToken where token = ?")
User findBySession(String token);
}
我还注意到您有 findByUuid
的 @Query
不需要,因为 Spring Data JPA 可以为您生成该查询。