[英]Spring Boot Spring Data JPA and Repositories
我非常熟悉“遗留”Spring 4 应用程序。 “遗留”是指不使用 Spring Boot 并使用 application-context.xml 文件和注释。 但是,我是 Spring Boot 和 Configuration 类的新手。
我正在创建一个新的 Spring Boot 应用程序,并将一些代码移动到我的旧 Spring 应用程序到这个新的 Spring Boot 应用程序中。 有了这个,我正在实施 Spring Data JPA 吗?
我已经有了实体,所以我只是把它带来了。我有一个正确的 application.properties 设置。 我按照我看到的所有示例中的描述创建了存储库,因此我有一个如下所示的存储库:
@Repository("contactDao")
public interface ContactDao extends CrudRepository<ContactEntity, Long>
{
}
所以,据我所知,findOne(Long id) 和 findAll() 等函数有很多……所有这些方法都是内置的。我什至能够对读取、写入数据库和这一切都很好。
所以,我现在想知道……我需要创建实现吗? 我的意思是因为我没有 EntityManager ......我需要一个吗?
我现在看到的所有示例都显示了与上面类似的界面,但没有 @Repository 注释:
public interface ContactDao extends CrudRepository<ContactEntity, Long>
{
}
我现在看到需要实现的示例:
@Repository("contactDao")
public class ContactDaoImpl implements ContactDao
{
@PersistenceContext
private EntityManager entityManager;
@Override
public ContactEntity findOne(Long contactId)
{
return entityManager.findOne(contactId);
}
}
我认为 Spring Data JPA 的承诺是不必有一个 Impl,但接口就足够了????????????
出现这种情况的原因是我现在正在测试我的业务服务,它抱怨我缺少 EntityManagerFactory ......我认为我不需要一个。
任何澄清的帮助将不胜感激。 我正在查看谷歌并访问所有类型的站点和 github 项目,但其中一些站点和项目......如果它们不是 2017 年的,它们很可能已经过时了。
我只想要通过当前标准构建这个项目的正确方法。
更新:
1) 放回我的接口 2) 删除了实现代码 3) DAO/存储库代码测试正常 4) 添加业务服务:
public interface ContactService
{
List<ContactEntity> getAllContacts();
List<ContactEntity> getContactsByUserId(long userId);
ContactEntity getContactById(long contactId);
ContactEntity add(ContactEntity newContact);
ContactEntity update(ContactEntity newContact);
void remove(long contactId);
}
这是服务的实际实现:
@Transactional
@Service("contactService")
public class ContactServiceImpl implements ContactService
{
@Autowired
private ContactDao contactDao; // THIS ERRORS
@Override
public List<ContactEntity> getAllContacts()
{
List<ContactEntity> contactList = (List<ContactEntity>) contactDao.findAll();
return contactList;
}
@Override
public List<ContactEntity> getContactsByUserId(long userId)
{
UserEntity userEntity = new UserEntity();
userEntity.setUserId(userId);
List<ContactEntity> contactList = contactDao.findByUser(userEntity);
return contactList;
}
... other methods ...
}
这是测试设置:
@Configuration
@ComponentScan("com.tomholmes.springboot.phonebook.server")
@EnableJpaRepositories(basePackages=
{"com.tomholmes.springboot.phonebook.server"})
@PropertySource(value = "classpath:application.properties")
public class TestServiceContextConfiguration
{ }
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestServiceContextConfiguration.class)
@Transactional
public class BaseServiceImplTests
{ }
最后,这是测试本身:
public class ContactServiceImplTest extends BaseServiceImplTests
{
@Autowired
private ContactService service;
@Test
public void testFetchAll() throws Exception
{
List<ContactEntity> contactEntityList = service.getAllContacts();
assertNotNull(contactEntityList);
}
}
这是错误:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:44)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'contactEmailService': Unsatisfied dependency expressed through field 'contactEmailDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contactEmailDao': Cannot create inner bean '(inner bean)#70ab80e3' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#70ab80e3': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
... 26 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contactEmailDao': Cannot create inner bean '(inner bean)#70ab80e3' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#70ab80e3': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:313)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:129)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1531)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1276)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 44 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#70ab80e3': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:634)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:448)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:299)
... 57 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1207)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
... 65 more
您不需要实现 ContactDao 接口。
想象一下,你有一个员工的数据库。 例如:
@Repository
public interface ContactDao extends CrudRepository<ContactEntity, Long>{
Employee findOne(Long id);
List<Employee> findByName(String name);
//etc...
}
然后在你的类中你实现业务逻辑或任何你想要的地方你可以编码:
@Service
public class ServiceImpl implement Service{
Autowired
ContactDao contactDao;
public Employee getEmployee(Long id){
return contactDao.findOne(id);
}
}
@Repository
或@Service
或其他注释,你告诉 Spring Boot 这些是 bean,所以它必须管理它们。
对于有关 EntityManager 的异常,请仔细阅读错误消息。 也许您创建的 bean 有问题,或者您没有创建。 谷歌它或发布它。
package com.wisdom.spring.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.wisdom.spring.model.students;
import com.wisdom.spring.repo.students_repo;
@RestController
@RequestMapping("/students")
public class studentController {
@Autowired
students_repo STDRepo;
@GetMapping(value = "/a")
public String a() {
return "hello";
}
@GetMapping(value = "/save")
public List<students> getStudents(){
System.out.println("Data returned");
return STDRepo.findAll();
}
@PostMapping(value = "/savestd")
public void saveBurger(students student) {
STDRepo.save(student);
}
}
package com.wisdom.spring.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class students {
@Id
@Column
private int s_id;
@Column
private String name;
@Column
private String address;
public students() {
}
public students(int s_id, String name, String address) {
this.s_id = s_id;
this.name = name;
this.address = address;
}
public int getS_id() {
return s_id;
}
public void setS_id(int s_id) {
this.s_id = s_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
package com.wisdom.spring.repo;
import org.springframework.data.jpa.repository.JpaRepository;
import com.wisdom.spring.model.students;
public interface students_repo extends JpaRepository<students,String> {
}
//pom
<?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 http://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.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.wisdom.spring</groupId>
<artifactId>myspringjpa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>my-spring-jpa</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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
//application config
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5433/finalproject
spring.datasource.username=postgres
spring.datasource.password=8855
spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
server.port=8585
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.