Spring Boot Spring数据JPA和存储库

时间:2018-02-26 20:14:46

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

我非常熟悉"遗产" 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 / Repository代码测试正常 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

2 个答案:

答案 0 :(得分:0)

您不需要实施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的例外,请仔细阅读错误消息。你创造的豆类可能有些不对劲,或者你没有。谷歌或发布它。

答案 1 :(得分:-2)

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