java - 如何在简单的 Spring Boot 应用程序中自动装配扩展 CrudRepository 的存储库?
问题描述
在高层次上 - 我正在尝试将 Spring Data JPA 与现有的 Spring Boot 应用程序一起使用。我已经阅读了https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories但似乎找不到我要找的东西。
我试图扩展“使用 JPA 访问数据”演示并遇到此错误。以下内容与演示代码之间的一些区别:
Autowired
用于在我的主 Spring Boot jar (JpaDemoApplication.java) 中使用存储库- 而不是
CommandLineRunner
在示例中使用,我使用的是@Scheduled
注释
org.springframework.beans.NotReadablePropertyException: Invalid property 'id' of bean class [java.lang.String]: Could not find field for property during fallback access!
at org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper.getPropertyValue(DirectFieldAccessFallbackBeanWrapper.java:58) ~[spring-data-commons-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.getId(JpaMetamodelEntityInformation.java:153) ~[spring-data-jpa-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.data.repository.core.support.AbstractEntityInformation.isNew(AbstractEntityInformation.java:42) ~[spring-data-commons-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.isNew(JpaMetamodelEntityInformation.java:237) ~[spring-data-jpa-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:553) ~[spring-data-jpa-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:371) ~[spring-data-commons-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:204) ~[spring-data-commons-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:657) ~[spring-data-commons-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:621) ~[spring-data-commons-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:605) ~[spring-data-commons-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366) ~[spring-tx-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99) ~[spring-tx-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:178) ~[spring-data-jpa-2.2.1.RELEASE.jar:2.2.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at com.sun.proxy.$Proxy67.save(Unknown Source) ~[na:na]
at com.regchecker.jpademo.JpaDemoApplication.run(JpaDemoApplication.java:22) ~[classes/:na]
项目.java:
package com.demo.jpademo;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Item {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String value;
/**
* @return the id
*/
public Long getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
/**
* @return the value
*/
public String getValue() {
return value;
}
/**
* @param value the value to set
*/
public void setValue(String value) {
this.value = value;
}
protected Item() {
}
public Item(String value) {
this.value = value;
}
@Override
public String toString() {
return "Value: " + value;
}
}
ItemRepository.java
package com.demo.jpademo;
import org.springframework.data.repository.CrudRepository;
public interface ItemRepository extends CrudRepository<Item, Long> {
void save (String value);
}
JpaDemoApplication.java
package com.demo.jpademo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
@EnableScheduling
@SpringBootApplication
public class JpaDemoApplication {
@Autowired
ItemRepository itemrepo;
public static void main(String[] args) {
SpringApplication.run(JpaDemoApplication.class, args);
}
@Scheduled(fixedRate=100000)
public void run() {
itemrepo.save("ABC");
System.out.println(itemrepo.count());
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo.jpademo</groupId>
<artifactId>jpa-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jpa-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
解决方案
改变
@Repository
public interface ItemRepository extends CrudRepository<Item, Long> {
// void save (String value);
}
和
@EnableScheduling
@SpringBootApplication
public class JpaDemoApplication {
@Autowired
ItemRepository itemrepo;
public static void main(String[] args) {
SpringApplication.run(JpaDemoApplication.class, args);
}
@Scheduled(fixedRate=100000)
public void run() {
Item item = new Item();
item.setValue("ABC");
itemrepo.save(item); // Item instance, not String
System.out.println(itemrepo.count());
}
}
请参阅保存方法文档。
推荐阅读
- java - 如何使用 StAX 合并具有特定条件的两个 XML 文件
- asp.net-core - IdentityServer 4 身份验证失败
- python - 使用 ValueError 构建自定义联合平均过程:层顺序需要 1 个输入,但它接收到 3 个输入张量
- unity3d - 视野从出生点消失
- perl - perl eval "...propagated" 记录在哪里
- c# - 我的 For 循环使用 Regex.Replace 关闭得太快了
- android - 带有 CASE 的 SQLite SELECT 不返回预期的输出
- css - 有没有办法计算居中 div 和屏幕边缘之间的宽度?
- xml - 如何在 Tomcat 9 中找到 xml.xsd
- python - 这个回溯错误是什么意思?提供了确切的错误消息