【问题标题】:spring jpa : how to only fetch EmbeddedCollection onlyspring jpa:如何仅获取 EmbeddedCollection
【发布时间】:2020-07-15 13:16:44
【问题描述】:

我有一个包含嵌入式集合的类

@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
public class User {

    @Id
    @GeneratedValue
    private long id;

    @Column(name = "user_name", nullable = false, unique = true)
    private String userName;

    @Column(name = "password", nullable = false)
    private String password;

    @Column(name = "email")
    private String email;

    @ElementCollection
    @CollectionTable(name = "mobile_numbers_List",joinColumns = @JoinColumn(name = "user_name",referencedColumnName = "user_name"))
    @Column(name = "mobile_number")
    private List<String> mobileNumbers;
}

现在我只想获取 mobileNumbers ,有什么办法只获取 mobileNumbers 吗??

我拥有的存储库类是

public interface UserRespository extends JpaRepository<User, Long> {

    Optional<User> getByUserNameIgnoreCase(String userName);

    @Query(value = "select mobileNumbers from User dao where upper(dao.userName) = upper(?1)")
    List<String> getByUserNameIgnoreCaseComplete(String userName);

}

现在我只想获取名称映射到手机号码的用户的手机号码,但运行上述代码会引发 QueryException。

这是确切的堆栈跟踪

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRespository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List database.users.UserRespository.getByUserNameIgnoreCaseComplete(java.lang.String)!
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$151/1741860261.getObject(Unknown Source) ~[na:na]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1247) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    ... 55 common frames omitted
Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List database.users.UserRespository.getByUserNameIgnoreCaseComplete(java.lang.String)!
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:93) ~[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:63) ~[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.java:76) ~[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromQueryAnnotation(JpaQueryFactory.java:56) ~[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:142) ~[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:209) ~[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:79) ~[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lookupQuery(RepositoryFactorySupport.java:566) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$mapMethodsToQuery$1(RepositoryFactorySupport.java:559) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor$$Lambda$760/276890300.apply(Unknown Source) ~[na:na]
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[na:1.8.0_40]
    at java.util.Iterator.forEachRemaining(Iterator.java:116) ~[na:1.8.0_40]
    at java.util.Collections$UnmodifiableCollection$1.forEachRemaining(Collections.java:1049) ~[na:1.8.0_40]
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) ~[na:1.8.0_40]
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512) ~[na:1.8.0_40]
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502) ~[na:1.8.0_40]
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_40]
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_40]
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[na:1.8.0_40]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.mapMethodsToQuery(RepositoryFactorySupport.java:561) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$new$0(RepositoryFactorySupport.java:551) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor$$Lambda$756/860988196.apply(Unknown Source) ~[na:na]
    at java.util.Optional.map(Optional.java:215) ~[na:1.8.0_40]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:551) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:324) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:297) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport$$Lambda$733/543410550.get(Unknown Source) ~[na:na]
    at org.springframework.data.util.Lazy.getNullable(Lazy.java:211) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.util.Lazy.get(Lazy.java:94) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:300) ~[spring-data-commons-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:121) ~[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    ... 67 common frames omitted
Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryException: not an entity [select mobileNumbers from UserDao dao where upper(dao.userName) = upper(?1)]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:723) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:23) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at sun.reflect.GeneratedMethodAccessor78.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_40]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_40]
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:350) ~[spring-orm-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at com.sun.proxy.$Proxy136.createQuery(Unknown Source) ~[na:na]
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:87) ~[spring-data-jpa-2.1.6.RELEASE.jar:2.1.6.RELEASE]
    ... 99 common frames omitted
Caused by: org.hibernate.QueryException: not an entity [select mobileNumbers from UserDao dao where upper(dao.userName) = upper(?1)]
    at org.hibernate.QueryException.generateQueryException(QueryException.java:120) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:219) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:143) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:119) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:605) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:714) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    ... 106 common frames omitted
Caused by: org.hibernate.QueryException: not an entity
    at org.hibernate.hql.internal.ast.tree.FromElementType.renderIdentifierSelect(FromElementType.java:177) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.hql.internal.ast.tree.FromElement.renderIdentifierSelect(FromElement.java:208) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.hql.internal.ast.tree.SelectClause.renderNonScalarIdentifiers(SelectClause.java:464) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.hql.internal.ast.tree.SelectClause.renderNonScalarSelects(SelectClause.java:424) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.hql.internal.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.java:247) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.hql.internal.ast.HqlSqlWalker.useSelectClause(HqlSqlWalker.java:1018) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:786) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:677) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:313) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:261) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:271) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:191) ~[hibernate-core-5.3.9.Final.jar:5.3.9.Final]
    ... 112 common frames omitted

【问题讨论】:

  • 您必须更精确地了解您想要实现的目标您想要一个用户的手机号码还是所有用户的手机号码?什么输出类型? List 还是 List>?您是否希望生成的 SQL 查询不包含来自用户实体的字段?
  • 希望编辑有所帮助

标签: spring-boot spring-data-jpa


【解决方案1】:

如果你只想获取手机号码,那么试试这个

@Query(value = "select m from User u inner join u.mobileNumbers m on upper(u.userName) = upper(?1)")
List<String> getByUserNameIgnoreCaseComplete(String userName);

【讨论】:

    【解决方案2】:

    如果你只想从你的 Object 中获取一个字段,你可以创建 JsonSerializer,例如:

        @JsonComponent
        public class UserJsonSerializer extends JsonSerializer<User> {
    // Your serialezer
    }
    

    【讨论】:

      【解决方案3】:

      当然Query中的UserDao是错误的,因为你的实体叫做User。 这样的事情应该可以工作。

      @Query(value = "select u.mobileNumbers from User u where upper(u.userName) = upper(?1)")
      List<String> getByUserNameIgnoreCaseComplete(String userName);
      

      【讨论】:

      • 对不起,我更改了类名,但忘记更改存储库名称。但是更改没有任何区别我得到了同样的错误,我已经用扩展同一类的存储库更新了问题......问题仍然存在。
      • 从您现在拥有的代码中,至少您需要将select mobileNumbers from User dao 更改为select dao.mobileNumbers from User dao
      • 遇到同样的异常
      猜你喜欢
      • 1970-01-01
      • 2016-09-07
      • 1970-01-01
      • 2013-03-07
      • 2019-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-03
      相关资源
      最近更新 更多