[Java| SpringBoot]存储库未被注入

huangapple go评论71阅读模式
英文:

[Java| SpringBoot]The Repository is not getting injected

问题

I've been getting into Java again after some years only dealing with javascript and typescript, and I'm trying to get into Spring Boot.

It sounds really fun and convenient, but I'm trying to do something simple and for some reason I can't get my repository to get injected into my service. It sounds something really simple, but I've been digging for hours and can't get it to work. I'm wondering if some of you can help me to understand what I'm doing wrong, please.

Thanks in advance

Projects (Entity)

package com.example.demo.modules.projects.entities;

import javax.persistence.*;

@Entity
@Table
public class Projects {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @Column
    private String project_name;
    @Column
    private String description;
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getProject_name() {
        return project_name;
    }
    public void setProject_name(String project_name) {
        this.project_name = project_name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}

The Repository

package com.example.demo.modules.projects.repositories;

import com.example.demo.modules.projects.entities.Projects;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface IProjectRepository extends JpaRepository<Projects, Long> {

}

CreateProjectsService

package com.example.demo.modules.projects.services;

import com.example.demo.modules.projects.entities.Projects;
import com.example.demo.modules.projects.repositories.IProjectRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CreateProjectService {

    @Autowired
    IProjectRepository iProjectRepository;

    public Projects execute(Projects project){
        System.out.println("Received " + project.toString());
        Projects CreatedProject= this.iProjectRepository.save(project);
        System.out.println("Created " + CreatedProject);
        return CreatedProject;
    }
}

The Error

It seems to not be injecting/instantiating correctly.

2020-10-09 00:56:08.774 ERROR 5856 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException: Cannot invoke "com.example.demo.modules.projects.repositories.IProjectRepository.save(Object)" because "this.iProjectRepository" is null] with root cause

java.lang.NullPointerException: Cannot invoke "com.example.demo.modules.projects.repositories.IProjectRepository.save(Object)" because "this.iProjectRepository" is null
	at com.example.demo.modules.projects.services.CreateProjectService.execute(CreateProjectService.java:17) ~[classes/:na]
	// ... rest of the stack trace

If you have any further questions or need assistance with specific parts of the code, please let me know.

英文:

I've been getting into Java again after some years only dealing with javascript and typescript, and I'm trying to get into Spring Boot.

It sounds really fun and convenient, but I'm trying to do something simple and for some reason I can't get my repository to get injected into my service. It sounds something really simple, but I've been digging for hours and can't get it to work.I'm wondering if some of you can help me to understand what I'm doing wrong ,please.

Thanks in advance

Projects (Entity)

package com.example.demo.modules.projects.entities;

import javax.persistence.*;

@Entity
@Table
public class Projects {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @Column
    private String project_name;
    @Column
    private String description;
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getProject_name() {
        return project_name;
    }
    public void setProject_name(String project_name) {
        this.project_name = project_name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}

The Repository

package com.example.demo.modules.projects.repositories;

import com.example.demo.modules.projects.entities.Projects;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;


@Repository
public interface IProjectRepository extends JpaRepository&lt;Projects, Long&gt; {
    
}

CreateProjectsService

package com.example.demo.modules.projects.services;

import com.example.demo.modules.projects.entities.Projects;
import com.example.demo.modules.projects.repositories.IProjectRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CreateProjectService {


    @Autowired
    IProjectRepository iProjectRepository;

    public Projects execute(Projects project){
        System.out.println(&quot;Received &quot; + project.toString());
        Projects CreatedProject= this.iProjectRepository.save(project);
        System.out.println(&quot;Created &quot; + CreatedProject);
        return CreatedProject;
    }
}

The Error

It seems to not be injecting/instantiating correctly.

2020-10-09 00:56:08.774 ERROR 5856 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException: Cannot invoke &quot;com.example.demo.modules.projects.repositories.IProjectRepository.save(Object)&quot; because &quot;this.iProjectRepository&quot; is null] with root cause

java.lang.NullPointerException: Cannot invoke &quot;com.example.demo.modules.projects.repositories.IProjectRepository.save(Object)&quot; because &quot;this.iProjectRepository&quot; is null
	at com.example.demo.modules.projects.services.CreateProjectService.execute(CreateProjectService.java:17) ~[classes/:na]
	at com.example.demo.ServerApplication.newEmployee(ServerApplication.java:26) ~[classes/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[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:564) ~[na:na]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:652) ~[tomcat-embed-core-9.0.38.jar:4.0.FR]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.38.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.38.jar:9.0.38]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
	at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na]

答案1

得分: 1

问题是因为您没有允许Spring实例化CreateProjectService并控制该bean,可能您是通过new CreateProjectService()实例化对象的。

推荐的方法是创建一个接口,例如ICreateProjectService,如下所示:

public interface ICreateProjectService {

    Projects execute(Projects project);

}

然后在CreateProjectService中实现ICreateProjectService,如下所示:

@Service
public class CreateProjectService implements ICreateProjectService {

    @Autowired
    private IProjectRepository iProjectRepository;

    @Override
    public Projects execute(Projects project) {
        System.out.println("Received " + project.toString());
        Projects CreatedProject = this.iProjectRepository.save(project);
        System.out.println("Created " + CreatedProject);
        return CreatedProject;
    }
}

然后在Controller层中,作为服务使用的示例,通过注入接口来自动装配您的服务,如下所示:

@RestController
@RequestMapping("/api/v1")
public class CreateProjectRest {

    @Autowired
    private ICreateProjectService iCreateProjectService;

    @PostMapping
    public Projects execute(Projects project) {
        iCreateProjectService.execute(project);
        // 您的代码在这里
    }
}

现在,Spring能够将CreateProjectService识别为一个具体的实现,将其实例化为一个Spring bean,将其保留在Spring容器中,并使其在任何被注入的地方可用于依赖注入。

希望这能有所帮助。

更新:

通过构造函数注入依赖项比通过字段或setter方法更加推荐。

@RestController
@RequestMapping("/api/v1")
public class CreateProjectRest {

    private ICreateProjectService iCreateProjectService;

    /* 在Spring 4.3之后不需要在构造函数上注解@Autowired。 */
    public CreateProjectRest(ICreateProjectService iCreateProjectService){
        this.iCreateProjectService = iCreateProjectService;
    }

    @PostMapping
    public Projects execute(Projects project) {
        iCreateProjectService.execute(project);
        // 您的代码在这里
    }
}
英文:

The issue is because you did not allow Spring to instantiate CreateProjectService and takes control of the bean, probably you instantiated the object with new CreateProjectService().

The recommended approach is to create an interface e.g. ICreateProjectService like below:

public interface ICreateProjectService {

    Projects execute(Projects project);

}

And then implement ICreateProjectService in CreateProjectService like below:

@Service
public class CreateProjectService implements ICreateProjectService {

    @Autowired
    private IProjectRepository iProjectRepository;

    @Override
    public Projects execute(Projects project) {
        System.out.println(&quot;Received &quot; + project.toString());
        Projects CreatedProject= this.iProjectRepository.save(project);
        System.out.println(&quot;Created &quot; + CreatedProject);
        return CreatedProject;
    }
}

Then in your Controller layer, as an example of the service usage, autowire your service by injecting the interface, like below:

@Restcontroller
@RequestMapping(&quot;/api/v1&quot;)
public class CreateProjectRest {

    @Autowired
    private ICreateProjectService iCreateProjectService;

    @PostMapping
    public Projects execute(Projects project) {
        createProjectService.execute(project);
        // your code here
    }
}

Now Spring is able to recognize CreateProjectService as a concrete implementation, instantiates it as a Spring bean, keeps it in Spring container and make it available for Dependency Injection wherever injected.

Hope this helps out.

UPDATE:

It is more advisable to inject dependencies via constructor than field or setter method.

@Restcontroller
@RequestMapping(&quot;/api/v1&quot;)
public class CreateProjectRest {

    private ICreateProjectService iCreateProjectService;
    
    /* No needed to annotate @Autowired after Spring 4.3.*/
    public CreateProjectRest(ICreateProjectService iCreateProjectService){
      this.iCreateProjectService = iCreateProjectService;
    }

    @PostMapping
    public Projects execute(Projects project) {
        createProjectService.execute(project);
        // your code here
    }
}

huangapple
  • 本文由 发表于 2020年10月9日 11:58:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/64273742.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定