Java Spring Boot JPA-保存到数据库时抛出Nullpointer异常

发布于 2025-01-30 06:29:39 字数 4390 浏览 3 评论 0原文

我正在使用Spring Boot(和Hibernate)进行小型应用程序。在制作此应用程序时,我遇到了一个奇怪的问题,当我使用DAO对象保存我创建给数据库的对象时。它引发了一个无效的指针例外,我还没有设法弄清楚为什么,我检查了通常的嫌疑人(di),但是我使用的注释@Autowired,因此应该有效。我几乎把头发撕掉了,也许您会看到我错过的是什么,谢谢?

编辑:我遵循了发布的说明。和。它可以正常工作,但是只有我评论我的DeleteCategoryByName方法。我已经进行了一些更改,而是将Demo1类重命名为Library Application。现在,我会收到错误:

ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'categoryService': Unsatisfied dependency expressed through field 'categoryDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'categoryDao': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Using named parameters for method public abstract java.lang.Void consid.programmeringstest.library.dao.CategoryDao.deleteCategoryByName(java.lang.String) but parameter 'Optional[categoryName]' not found in annotated query 'DELETE FROM category WHERE name = :category_name '!

我的代码

dao-class

package library.dao;

import library.domain.Category;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;


public interface CategoryDao extends JpaRepository<Category, Long> {
    default Category findByIdOrThrow(Long id) {
        return findById(id).orElseThrow();
    }
    
    @Modifying
    @Query("DELETE FROM category WHERE name = :category_name ")
    public void deleteCategoryByName(@Param("categoryName") String categoryName);
}

域级别的doain-class

package library.domain;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Category implements Serializable {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String categoryName;
    
    public Category() {
    }
    
    public Category(String name) {
        this.categoryName = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String name) {
        this.categoryName = name;
    }
    
}

the Service-class class

package library.service;

import library.dao.CategoryDao;
import library.domain.Category;
import org.springframework.beans.factory.annotation.Autowired;


public class CategoryService {
    
    @Autowired
    private CategoryDao categoryDao;
    
    public Category createCategory() {
        Category result = new Category();
        return categoryDao.save(result);
    }
    
    public Category createCategory(String name) {
        Category result = new Category(name);
        return categoryDao.save(result);
    }
    
    public void deleteCategoryByName(String name) {
        categoryDao.deleteCategoryByName(name);
    }
    
}

package library;

import library.dao.CategoryDao;
import library.domain.Category;
import library.service.CategoryService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableAutoConfiguration
public class LibraryApplication {
    public static void main(String[] args) {
        SpringApplication.run(LibraryApplication.class, args);
    }
    
  @Bean
  public CommandLineRunner demo(CategoryDao categoryDao) {
    return (args) -> {
        categoryDao.save(new Category("Test"));
        Category category = categoryDao.findByIdOrThrow(1);
        System.out.println(category.getCategoryName());
    };
  }
}

图片表和列。

I'm making a small application using Spring Boot (and hibernate). I've encountered a strange problem while making this app, when I use my DAO object to save an object I've created to the database. It throws a null pointer exception and I haven't managed to figure out why, I've checked the usual suspect (DI) but I am using the annotation @autowired so it should work. I'm nearly tearing my hair out, maybe you'll see what it is that I've missed, thank you?

EDIT: I've followed the instructions posted by . and ., and it works but only if I comment out my deleteCategoryByName method. I've made some changes below, I've renamed the Demo1 class to LibraryApplication instead. I now get the error:

ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'categoryService': Unsatisfied dependency expressed through field 'categoryDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'categoryDao': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Using named parameters for method public abstract java.lang.Void consid.programmeringstest.library.dao.CategoryDao.deleteCategoryByName(java.lang.String) but parameter 'Optional[categoryName]' not found in annotated query 'DELETE FROM category WHERE name = :category_name '!

My code

The DAO-class

package library.dao;

import library.domain.Category;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;


public interface CategoryDao extends JpaRepository<Category, Long> {
    default Category findByIdOrThrow(Long id) {
        return findById(id).orElseThrow();
    }
    
    @Modifying
    @Query("DELETE FROM category WHERE name = :category_name ")
    public void deleteCategoryByName(@Param("categoryName") String categoryName);
}

The Domain-class

package library.domain;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Category implements Serializable {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String categoryName;
    
    public Category() {
    }
    
    public Category(String name) {
        this.categoryName = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String name) {
        this.categoryName = name;
    }
    
}

The Service-class

package library.service;

import library.dao.CategoryDao;
import library.domain.Category;
import org.springframework.beans.factory.annotation.Autowired;


public class CategoryService {
    
    @Autowired
    private CategoryDao categoryDao;
    
    public Category createCategory() {
        Category result = new Category();
        return categoryDao.save(result);
    }
    
    public Category createCategory(String name) {
        Category result = new Category(name);
        return categoryDao.save(result);
    }
    
    public void deleteCategoryByName(String name) {
        categoryDao.deleteCategoryByName(name);
    }
    
}

package library;

import library.dao.CategoryDao;
import library.domain.Category;
import library.service.CategoryService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableAutoConfiguration
public class LibraryApplication {
    public static void main(String[] args) {
        SpringApplication.run(LibraryApplication.class, args);
    }
    
  @Bean
  public CommandLineRunner demo(CategoryDao categoryDao) {
    return (args) -> {
        categoryDao.save(new Category("Test"));
        Category category = categoryDao.findByIdOrThrow(1);
        System.out.println(category.getCategoryName());
    };
  }
}

Picture of the table and column.

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

陌伤浅笑 2025-02-06 06:29:39

1.您应该添加@component/@service上面的categoryservice

2.您未正确启动Spring Boot应用程序。您应该这样做,而不是demo1

package library;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AccessingDataJpaApplication {

  public static void main(String[] args) {
    SpringApplication.run(AccessingDataJpaApplication.class, args);
  }

}

有关此的更多信息,请参见 https://spring.io/guides/gs/accessing-data-jpa/

直接直接回答您的问题,您获得NPE的原因是categorydao in in categoryservice为null,因为您未正确启动弹簧启动。

ps

您应该注意,在层次结构中“更高”的软件包(library软件包)中,将应用程序类(访问datajpaapplication)在软件包中在这本书中,否则您将不得不在@springbootapplication中提及正确的软件包注释

1.you should add a @Component / @Service above CategoryService

2.you are not starting spring boot app correctly . you should do this instead of Demo1:

package library;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AccessingDataJpaApplication {

  public static void main(String[] args) {
    SpringApplication.run(AccessingDataJpaApplication.class, args);
  }

}

more on this can be found in https://spring.io/guides/gs/accessing-data-jpa/

answering your question directly , the reason your are getting NPE is because categoryDao in CategoryService is null , since you are not starting spring boot correctly.

P.S

you should note that having your app class (AccessingDataJpaApplication) in a package "higher" in the hierarchy(library package) then the rest of your components will make this work out of the book , otherwise you will have to mention the correct packages in the @SpringBootApplication annotation

╄→承喏 2025-02-06 06:29:39

首先,您需要添加的是@springbootapplication到主类。第二 - springapplication.run(demo1.class,args);在main(可执行)方法的第一行。而且,不要忘记将@service添加到您的应用程序的服务类中。

First what you need to add is @SpringBootApplication to the main class. Second - SpringApplication.run(Demo1.class, args); at the first line of main(executable) method. And also, don't forget to add @Service to the service class of your application.

空城旧梦 2025-02-06 06:29:39

您的DAO类的参数名称categoryName。它应该是category_name。并且还使用saveandflush()而不是save()

categorydao.java

package library.dao;

import library.domain.Category;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;


public interface CategoryDao extends JpaRepository<Category, Long> {
    default Category findByIdOrThrow(Long id) {
        return findById(id).orElseThrow();
    }
    
    @Modifying
    @Query("DELETE FROM category WHERE name = :category_name ")
    public void deleteCategoryByName(@Param("category_name") String categoryName);
}

Your DAO class has incorrect parameter name categoryName. It should be category_name. And also use saveAndFlush() rather than just save()

CategoryDao.java

package library.dao;

import library.domain.Category;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;


public interface CategoryDao extends JpaRepository<Category, Long> {
    default Category findByIdOrThrow(Long id) {
        return findById(id).orElseThrow();
    }
    
    @Modifying
    @Query("DELETE FROM category WHERE name = :category_name ")
    public void deleteCategoryByName(@Param("category_name") String categoryName);
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文