簡體   English   中英

Spring Boot Spring Data JPA 和存儲庫

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM