0

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

1

3 Answers 3

1

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

Sign up to request clarification or add additional context in comments.

4 Comments

Hi, thank you it works now but only when I comment out the other method in my DAO-class.
shouldnt this be : @Query("DELETE FROM category WHERE name = :categoryName ") instead of: @Query("DELETE FROM category WHERE name = :category_name ") it should match your @Param("categoryName") annotation
if it works for you please marked as answered , Thanks!
Thank you so much for all the help, it worked! Althought I also got a QueryException but that got solved by changing it from the table name category to the class name Category.
1

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.

1 Comment

Hi, thank you, I now get IllegalStateException unless I comment out the other method in the DAO-class.
1

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);
}

1 Comment

Thank you so much for all the help, it worked! Althought I also got a QueryException but that got solved by changing it from the table name category to the class name Category.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.