带有属性表达式

时间:2017-01-05 00:09:26

标签: spring hibernate spring-boot spring-data spring-data-jpa

我正在尝试使用Property Expression创建spring数据JPA存储库方法,但在启动Spring Boot应用程序时出错。

package com.ourkid.springdata;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.stereotype.Repository;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.io.Serializable;
import java.sql.Date;

@SpringBootApplication
@EnableJpaRepositories
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

@Repository
interface TimeExtensionRepository extends JpaRepository<TimeExtension, Long> {
    TimeExtension findByStatus_ShortNameAndBusinessDateAndWorkplace(String shortName, Date businessDate, Workplace workplace);
}

@Entity
class Workplace implements Serializable {

    public final static long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String description;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

@Entity
class Status implements Serializable {

    public final static long serialVersionUID = 2L;

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String shortName;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getShortName() {
        return shortName;
    }

    public void setShortName(String shortName) {
        this.shortName = shortName;
    }
}

@Entity
class TimeExtension implements Serializable {

    public final static long serialVersionUID = 3L;

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private Date businessDate;

    @Column(nullable = false)
    private Workplace workplace;

    @Column(nullable = false)
    private Status status;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Date getBusinessDate() {
        return businessDate;
    }

    public void setBusinessDate(Date businessDate) {
        this.businessDate = businessDate;
    }

    public Workplace getWorkplace() {
        return workplace;
    }

    public void setWorkplace(Workplace workplace) {
        this.workplace = workplace;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }
}

简单的repo方法有效,但我无法让这个属性表达式正常工作。我使用Spring 1.4.3.RELEASE与依赖spring-boot-starter-data-jpa和Java 8。

错误和整个输出如下:

/Library/Java/JavaVirtualMachines/jdk1.8.0_74.jdk/Contents/...

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.3.RELEASE)

2017-01-04 23:55:25.092  INFO 1788 --- [           main] com.ourkid.springdata.DemoApplication    : Starting DemoApplication on SRA-MBA.local with PID 1788 (/Users/saj/Downloads/demo/target/classes started by saj in /Users/saj/Downloads/demo)
2017-01-04 23:55:25.096  INFO 1788 --- [           main] com.ourkid.springdata.DemoApplication    : No active profile set, falling back to default profiles: default
2017-01-04 23:55:25.238  INFO 1788 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5427c60c: startup date [Wed Jan 04 23:55:25 GMT 2017]; root of context hierarchy
2017-01-04 23:55:26.850  INFO 1788 --- [           main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2017-01-04 23:55:26.875  INFO 1788 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
    name: default
    ...]
2017-01-04 23:55:26.968  INFO 1788 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.0.11.Final}
2017-01-04 23:55:26.969  INFO 1788 --- [           main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2017-01-04 23:55:26.971  INFO 1788 --- [           main] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
2017-01-04 23:55:27.093  INFO 1788 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2017-01-04 23:55:27.208  INFO 1788 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2017-01-04 23:55:27.717  INFO 1788 --- [           main] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000227: Running hbm2ddl schema export
2017-01-04 23:55:27.730  INFO 1788 --- [           main] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000230: Schema export complete
2017-01-04 23:55:27.774  INFO 1788 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2017-01-04 23:55:28.063  WARN 1788 --- [           main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'timeExtensionRepository': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Illegal attempt to dereference path source [null.status] of basic type
2017-01-04 23:55:28.063  INFO 1788 --- [           main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2017-01-04 23:55:28.063  INFO 1788 --- [           main] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000227: Running hbm2ddl schema export
2017-01-04 23:55:28.070  INFO 1788 --- [           main] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000230: Schema export complete
2017-01-04 23:55:28.079  INFO 1788 --- [           main] utoConfigurationReportLoggingInitializer : 

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-01-04 23:55:28.092 ERROR 1788 --- [           main] o.s.boot.SpringApplication               : Application startup failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'timeExtensionRepository': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Illegal attempt to dereference path source [null.status] of basic type
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1589) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:554) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:740) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) ~[spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
    at com.ourkid.springdata.DemoApplication.main(DemoApplication.java:21) [classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_74]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_74]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_74]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_74]
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) [idea_rt.jar:na]
Caused by: java.lang.IllegalStateException: Illegal attempt to dereference path source [null.status] of basic type
    at org.hibernate.jpa.criteria.path.AbstractPathImpl.illegalDereference(AbstractPathImpl.java:82) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.jpa.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:174) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final]
    at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:622) ~[spring-data-jpa-1.10.6.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:576) ~[spring-data-jpa-1.10.6.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.getTypedPath(JpaQueryCreator.java:334) ~[spring-data-jpa-1.10.6.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.build(JpaQueryCreator.java:277) ~[spring-data-jpa-1.10.6.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.toPredicate(JpaQueryCreator.java:182) ~[spring-data-jpa-1.10.6.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:109) ~[spring-data-jpa-1.10.6.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:49) ~[spring-data-jpa-1.10.6.RELEASE.jar:na]
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:109) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:88) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:73) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.<init>(PartTreeJpaQuery.java:118) ~[spring-data-jpa-1.10.6.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$CountQueryPreparer.<init>(PartTreeJpaQuery.java:241) ~[spring-data-jpa-1.10.6.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:68) ~[spring-data-jpa-1.10.6.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:103) ~[spring-data-jpa-1.10.6.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:214) ~[spring-data-jpa-1.10.6.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:77) ~[spring-data-jpa-1.10.6.RELEASE.jar:na]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:435) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:220) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:280) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:266) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92) ~[spring-data-jpa-1.10.6.RELEASE.jar:na]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1648) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1585) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
    ... 20 common frames omitted


Process finished with exit code 1

此问题与https://jira.spring.io/browse/DATAJPA-476中报告的内容类似,但基本错误已修复。

2 个答案:

答案 0 :(得分:1)

也许我错过了SpringJPA的一些新功能,但对我而言,您的实体上看起来没有任何关系。

TimeExtension实体应与StatusWorkplace有任何关系。类似@OneToMany@ManyToOne@OneToOne@ManyToMany的内容。所以JPA知道实体之间的关系。

答案 1 :(得分:1)

更改为TimeExtension后,修复了此问题。

@Entity
class TimeExtension implements Serializable {

    public final static long serialVersionUID = 3L;

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private Date businessDate;

    @OneToOne
    @JoinColumn(nullable = false, name = "workplace_id")
    private Workplace workplace;

    @OneToOne
    @JoinColumn(nullable = false, name = "status_id")
    private Status status;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Date getBusinessDate() {
        return businessDate;
    }

    public void setBusinessDate(Date businessDate) {
        this.businessDate = businessDate;
    }

    public Workplace getWorkplace() {
        return workplace;
    }

    public void setWorkplace(Workplace workplace) {
        this.workplace = workplace;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }
}