[英]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.