2013-11-01 3 views
1

조인을 사용하여 매우 단순한 JPQL을 만들려고하는데 성공하지 못했습니다. 사용자 ID가 주어지면 사용자의 가장 최근 로그인 날짜를 얻고 싶습니다. Spring Data JPA + Hibernate를 사용하고 있습니다.JPQL JOIN 쿼리

@Table(name = "activity") 
@SuppressWarnings("serial") 
public class Activity implements Serializable { 
@Id 
@GeneratedValue 
private Long id; 

@Column(name = "date", insertable = true, nullable = false, updatable = false) 
@Temporal(TemporalType.TIMESTAMP) 
private Date date; 

@Column(insertable = true, name = "organization_id", nullable = true, updatable = true, unique = false) 
@Basic(optional = true) 
private Long organizationId; 

@Column(insertable = true, name = "operation", nullable = false, updatable = true, unique = false) 
@Basic(optional = false) 
private String operation; 

//getters and setters 
} 

그것은 LoginAttempt을 포함하여 다른 테이블의 다수 포함되어 있습니다 :

나는 테이블 활동이 포함 된 MySQL 데이터베이스가

@Table(name = "login_attempt") 
@SuppressWarnings("serial") 
public class LoginAttempt implements Serializable{ 

@Id 
@GeneratedValue 
private Long id; 

@OneToOne(fetch = FetchType.EAGER, optional = false) 
@Basic(optional = false) 
@JoinColumn(name = "activity_id", insertable = true, nullable = false, unique = false, updatable = false) 
private Activity activity; 

@Column(insertable = true, name = "user_id", nullable = true, updatable = true, unique = false) 
@Basic(optional = true) 
private Long userId; 

@Column(insertable = true, name = "user_email", nullable = true, updatable = true, unique = false) 
@Basic(optional = true) 
private String userEmail; 

@Column(insertable = true, name = "login_successful", nullable = false, updatable = true, unique = false) 
@Basic(optional = false) 
private boolean loginSuccessful; 

//getters and setters 
} 

다른 모든 테이블이라는 컬럼을 사용하여 작업을 참조 "activity_id ".

이것은 하나의 메소드와 @Query 어노테이션이있는 나의 DAO입니다.

public interface MyDAO extends JpaRepository<Activity, Long> { 

@Query("SELECT a FROM Activity a, LoginAttempt la JOIN a.id la WHERE la.user_email = (:userId) AND a.date = (SELECT MAX(a.date))") 
public Activity findMostRecentLoginForUser(@Param("userId") Long userId); 

} 

나는 간단한 그것이 작동하는 @query의 모든 문을 선택, 그래서 내가 제대로 데이터베이스에 연결하고있어 다시 모든 것을 얻을 수 있어요합니다. 처음에는 쿼리에 대한 유효성 검사 오류가 많이 발생했지만 지금은 다음과 같은 부분 스택 트레이스가 표시됩니다.

Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.domain.Activity com.dao.MyDAO.findMostRecentLoginForUser(java.lang.Long)! 
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:97) 
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:66) 
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.fromQueryAnnotation(SimpleJpaQuery.java:169) 
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:114) 
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:160) 
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:68) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:290) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:158) 
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:162) 
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:44) 
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142) 
... 44 more 
Caused by: java.lang.NullPointerException 
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromJoinElement(HqlSqlWalker.java:393) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.joinElement(HqlSqlBaseWalker.java:3645) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3431) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3309) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:706) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:562) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:299) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:247) 
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:250) 
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:185) 
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:138) 
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:105) 
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80) 
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:168) 
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:221) 
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:199) 
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1778) 
at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:291) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:601) 
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:366) 
at com.sun.proxy.$Proxy33.createQuery(Unknown Source) 
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:91) 
... 54 more 

내 뇌는 튀긴 나는 내가 읽은 예제의 둘레에 내 머리를 얻을 수 없습니다. 어떤 도움을 주셔서 감사합니다. 감사.

답변

0

쿼리의 형식이 잘못되었습니다. 서브 쿼리가 선택하는 내용을 지정하지 않았습니다. 에서까지입니다. 또한 LoginAttempt에서 Activity으로의 직접 참조가 있으므로 명시 적 조인을 수행 할 필요가 없습니다. 이 (안된) 같은 것을보십시오 :

SELECT la.activity FROM LoginAttempt la 
WHERE la.user_email = :userId 
AND la.activity.date = (SELECT MAX(la2.activity.date) FROM LoginAttempt la2 
         WHERE la2.user_email = :userId) 

하위 쿼리는 주어진 사용자에 대한 가장 최근의 날짜를 선택합니다. 외부 쿼리는 지정된 사용자에 대해 Activity을 선택하고 날짜는 하위 쿼리의 결과입니다.

+0

Perfect! 내가 바보 인 것을 깨달았을 때 실제로 조인을 사용하지 않았습니다. 답변 해주셔서 감사합니다! :-) – tikka