Introduction
I have been trying to solve this problem for a long time now. I have searched for awnsers and tried many solutions, which failed. I am using Spring Boot version 3.0.0, and spring-boot-starter-graphql version 3.0.0. I will provide (what i belive to be) all the relevant information to solve this problem.
Files
pom.xml
<?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 https://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>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>gorgeousSandwich</groupId>
<artifactId>promotion</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Promotion Microservice</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-graphql</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.graphql</groupId>
<artifactId>spring-graphql-test</artifactId>
<scope>test</scope>
</dependency>
<!-- OPEN API 3 (Swagger) -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
PromotionController.java
#AllArgsConstructor
#Controller
public class PromotionController {
private static final Logger LOGGER = LoggerFactory.getLogger(PromotionController.class);
private final IPromotionService service;
private final IPromotionMapper mapper;
#MutationMapping
public GraphQLPromotionDTO createPromotion(#Argument PromotionInput promotion) {
try {
PromotionDTO promotionDTO = promotion.toDTO();
LOGGER.trace(String.format("Requesting the creation of a new promotion (%s)", promotionDTO));
promotionDTO = service.createPromotion(promotionDTO);
LOGGER.info("Order successfully created");
return mapper.toGraphQLDTO(promotionDTO);
} catch (Exception e) {
LOGGER.error("Could not create Shop!", e);
return null;
}
}
#QueryMapping
public List<GraphQLPromotionDTO> listAllPromotions() {
System.out.println("Hehehe");
Iterable<PromotionDTO> itr = service.getAll();
List<GraphQLPromotionDTO> l = new ArrayList<>();
itr.forEach(dto -> l.add(mapper.toGraphQLDTO(dto)));
LOGGER.info("Retrieving all promotions");
return l;
}
#QueryMapping
public String health() {
return "All systems Online!";
}
record PromotionInput(Float percentage, String from, String to, String shopId, PromotionType promotionType) {
PromotionDTO toDTO() throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
return new PromotionDTO(null, percentage, format.parse(from), format.parse(to), Long.parseLong(shopId), promotionType);
}
}
}
schema.graphqls
schema {
query: Query
mutation: Mutator
}
type Mutator{
createPromotion (
promotion: PromotionInput
) : GraphQLPromotionDTO
}
type Query{
listAllPromotions : [GraphQLPromotionDTO],
health: String
}
input PromotionInput{
percentage: Float
from: String
to: String
shopId: ID
promotionType: PromotionType
}
enum PromotionType{
GLOBAL,
LOCAL
}
type GraphQLPromotionDTO {
id: ID
percentage : Float
from : String
to : String
shopId : ID
promotionType: PromotionType
}
Promotion.java
package gorgeousSandwich.promotion.Domain;
import gorgeousSandwich.promotion.Shared.domain.patterns.IAggregateRoot;
import gorgeousSandwich.promotion.Shared.domain.patterns.IEntity;
import gorgeousSandwich.promotion.Shared.domain.patterns.IEntityId;
import gorgeousSandwich.promotion.Shared.domain.valueobjects.Percentage;
import gorgeousSandwich.promotion.Shared.domain.valueobjects.TimeOfEffect;
import jakarta.persistence.*;
import org.springframework.data.annotation.Id;
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
#Entity
public abstract class Promotion implements IAggregateRoot<PromotionId> {
#EmbeddedId
private PromotionId id;
#Embedded
private TimeOfEffect timeOfEffect;
#Embedded
private Percentage percentage;
#Enumerated
private PromotionType type;
Promotion(TimeOfEffect timeOfEffect, Percentage percentage, PromotionType type) {
this.id = new PromotionId();
this.timeOfEffect = timeOfEffect;
this.percentage = percentage;
this.type=type;
}
Promotion(PromotionId id, TimeOfEffect timeOfEffect, Percentage percentage, PromotionType type) {
this.id = id;
this.timeOfEffect = timeOfEffect;
this.percentage = percentage;
this.type=type;
}
protected Promotion() {
}
#Override
public boolean sameAs(IEntity<? extends IEntityId> otherEntity) {
if (otherEntity instanceof Promotion) {
Promotion otherPromotion = ((Promotion) otherEntity);
return obtainId().id().equals(otherPromotion.obtainId().id());
}
return false;
}
#Override
public PromotionId obtainId() {
return id;
}
public TimeOfEffect getTimeOfEffect() {
return timeOfEffect;
}
public Percentage getPercentage() {
return percentage;
}
public PromotionType getType() {
return type;
}
}
GraphQLPromotionDTO.java
package gorgeousSandwich.promotion.Domain;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
#AllArgsConstructor(access = AccessLevel.PUBLIC)
public class GraphQLPromotionDTO {
public String id;
public float percentage;
public String from;
public String to;
public String shopId;
public PromotionType promotionType;
}
PromotionType.java
package gorgeousSandwich.promotion.Domain;
public enum PromotionType {
LOCAL,
GLOBAL;
}
Thaks for all the help
What i have tried already
I have tried to:
Match the types of the DTO in the schema to the code
#SchemaMapping instead of #QueryMapping and/or #MutationMapping
Debug any endpoint (but none worked)
Edit
Ok, i have already made progress. I can perform queries but mutations are still not working.
For those who have the same issue as myself, i found the solution by learning how to spell.
Mutator
must change to
Mutation
Result:
schema {
query: Query
mutation: Mutation
}
type Mutation{
createPromotion (
promotion: PromotionInput!
) : GraphQLPromotionDTO
}
type Query{
listAllPromotions : [GraphQLPromotionDTO!]!,
health: String!
}
input PromotionInput{
percentage: Float!
from: String!
to: String!
shopId: ID
promotionType: PromotionType!
}
enum PromotionType{
GLOBAL,
LOCAL
}
type GraphQLPromotionDTO {
id: ID!
percentage : Float!
from : String!
to : String!
shopId : ID
promotionType: PromotionType!
}
PS: Added null verification to each type
Related
Basically what the title says. No errors show in the console so I have no idea what's wrong. I am using CrudRepository. The task is to make a REST API for a game store. I am trying to access localhost:8080/game URL but 404 keeps happening.
Edit: changed #PostMapping() and #GetMapping() to #PostMapping and #GetMapping
GameStoreApplication.java:
package com.game_store.si2;
#SpringBootApplication
#ComponentScan("com.game_store.si2.repository")
public class GameStoreApplication {
public static void main(String[] args) {
SpringApplication.run(GameStoreApplication.class, args);
}
}
GameController.java:
package com.game_store.si2.controller;
#RestController #RequestMapping("/game")
public class GameController {
#Autowired
private GameRepository repository;
#PostMapping
public ResponseEntity<Game> newGame(#RequestBody Game novoGame) {
if(novoGame.getTitulo() != null) {
repository.save(novoGame);
return new ResponseEntity<>(HttpStatus.CREATED);
}
else {
return new ResponseEntity<Game>(novoGame, HttpStatus.UNPROCESSABLE_ENTITY);
}
}
#GetMapping("/{id}")
public ResponseEntity<Game> findGame(#PathVariable int id){
Optional<Game> gameObtido = repository.findById(id);
if(!gameObtido.isPresent()) {
return new ResponseEntity<Game>(HttpStatus.OK);
}
return new ResponseEntity<Game>(HttpStatus.NOT_FOUND);
}
#GetMapping
public Iterable<Game> listGames(){
return repository.findAll();
}
#DeleteMapping("/{id}")
public ResponseEntity<Game> deleteGame(#PathVariable int id){
Game gameObtido = repository.findById(id).orElse(null);
if(gameObtido != null) {
repository.delete(gameObtido);
return new ResponseEntity<Game>(gameObtido, HttpStatus.NO_CONTENT);
}
return new ResponseEntity<Game>(HttpStatus.NOT_FOUND);
}
#PutMapping("/update/{id}")
public ResponseEntity<Game> updateGame(#PathVariable int id,#RequestBody Game game){
Game existeGame = repository.findById(id).orElse(null);
if(existeGame != null) {
existeGame.setImgUrl(game.getImgUrl());
existeGame.setPreco(game.getPreco());
existeGame.setTitulo(game.getTitulo());
repository.save(existeGame);
return new ResponseEntity<Game>(existeGame, HttpStatus.OK);
}
return new ResponseEntity<Game>(HttpStatus.NOT_FOUND);
}
}
Game.java:
package com.game_store.si2.model;
#Entity #Getter #Setter #NoArgsConstructor
public class Game {
#Id #GeneratedValue(strategy = GenerationType.SEQUENCE)
private int id;
private String titulo;
private String ImgUrl;
private double preco;
private int numVendas;
}
GameRepository.java:
package com.game_store.si2.repository;
#RepositoryRestResource(collectionResourceRel = "game", path = "game")
public interface GameRepository extends CrudRepository<Game, Integer> {
}
pom.xml:
<?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 https://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.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.game_store</groupId>
<artifactId>game_store</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>game_store</name>
<description>Projeto de game store de SI2</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
GET and POST return:
{
"timestamp": "2020-09-10T03:41:47.478+00:00",
"status": 404,
"error": "Not Found",
"message": "",
"path": "/game"
}
You can replace #GetMapping() to #GetMapping and #PostMapping() to #PostMapping
in below method respectively like
#GetMapping
public Iterable<Game> listGames(){
return repository.findAll();
}
#PostMapping
public ResponseEntity<Game> newGame(#RequestBody Game novoGame) {
if(novoGame.getTitulo() != null) {
repository.save(novoGame);
return new ResponseEntity<>(HttpStatus.CREATED);
}
else {
return new ResponseEntity<Game>(novoGame, HttpStatus.UNPROCESSABLE_ENTITY);
}
}
To use default value of GetMapping and PostMapping you can use
#GetMapping
#PostMapping
or
#GetMapping("")
#PostMapping("")
just rename #PostMapping() to #PostMapping
I am not able to run application its show error as follows,
APPLICATION FAILED TO START
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.apache.catalina.authenticator.AuthenticatorBase.startInternal(AuthenticatorBase.java:1321)
The following method did not exist:
javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;
The method's class, javax.servlet.ServletContext, is available from the following locations:
jar:file:/D:/Comau_Mes/datemes/lib/javax.servlet.jar!/javax/servlet/ServletContext.class
jar:file:/C:/Users/YASH/.m2/repository/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar!/javax/servlet/ServletContext.class
jar:file:/C:/Users/YASH/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/9.0.35/tomcat-embed-core-9.0.35.jar!/javax/servlet/ServletContext.class
It was loaded from the following location:
file:/D:/Comau_Mes/datemes/lib/javax.servlet.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of javax.servlet.ServletContext
Process finished with exit code 0
Files as follows,
File-----> Product.java
#Entity
#Table(name="product")
public class Product {
#Id
private String id;
private String name;
private double price;
private int quantity;
private boolean status;
#JsonFormat(pattern ="", shape = JsonFormat.Shape.STRING)
#Column(name = "date_created")
private String dateCreated;
public String getId() {
return id;
}
//netal
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public String getDateCreated() {
return dateCreated;
}
public void setDateCreated(String dateCreated) {
this.dateCreated = dateCreated;
}
}
File --> ProductController
#RestController
#RequestMapping("api/product")
public class ProductController {
#Autowired
private ProductServices productServices;
#RequestMapping(value = "findall", method = RequestMethod.GET,
produces = {MimeTypeUtils.APPLICATION_JSON_VALUE})
public ResponseEntity<Iterable<Product>> findAll(){
try {
return new ResponseEntity<Iterable<Product>>
(productServices.findAll(),HttpStatus.OK);
}catch (Exception e){
return new ResponseEntity<Iterable<Product>>(HttpStatus.BAD_REQUEST);
}
}
}
File --> ProductRepository
#Repository("ProductRepository")
public interface ProductRepository extends CrudRepository<Product,String> {
}
File --> ProductServices
public interface ProductServices {
public Iterable<Product> findAll();
public Product save(Product product);
}
File --> ProductServicesImpl
#Service("productServices")
public class ProductServicesImpl implements ProductServices {
#Autowired
private ProductRepository productRepository;
#Override
public Iterable<Product> findAll() {
return productRepository.findAll();
}
#Override
public Product save(Product product) {
return productRepository.save(product);
}
}
File --> DatemesApplication
#SpringBootApplication
public class DatemesApplication {
public static void main(String[] args) {
SpringApplication.run(DatemesApplication.class, args);
}
}
File --> Pom.xml
<?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 https://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.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>datemes</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>datemes</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</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.2.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I'm using SpringBoot for my web app and I'm encountering the following error:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'heroController' defined in file [D:\Projects\Java\mydbexxcercise\target\classes\com\db\controllers\HeroController.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.db.controllers.HeroController]: Constructor threw exception; nested exception is java.lang.NullPointerException.
These are my classes:
DBApp class(main class):
package com.db.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
/*
* DAL - Data Access Layer
* BL - Business Layer
*
* */
#SpringBootApplication
#ComponentScan(basePackages = {"com.db.controllers","com.db.services"})
#EnableJpaRepositories(basePackages = "com.db.repositories")
#EntityScan(basePackages = "com.db.entities")
public class DBApp
{
public enum PowerCatagory{SpecialPower,Weapon,Machines}
private static ConfigurableApplicationContext appContext;
public static void main(String[] args)
{
appContext = SpringApplication.run(DBApp.class,args);
}
public static ConfigurableApplicationContext getAppContext()
{
return appContext;
}
}
HeroRepository class:
#Repository
public interface HeroRepository extends JpaRepository<Hero, Integer>
{
}
Hero entity class:
package com.db.entities;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import com.db.app.DBApp;
import org.postgresql.geometric.PGpolygon;
import org.springframework.stereotype.Component;
#Entity
#Table(name="hero")
public class Hero
{
public int getHid() {
return hid;
}
public PGpolygon getArea() {
return area;
}
public String getSpower() {
return spower;
}
public String getFname() {
return fname;
}
public String getLname() {
return lname;
}
public DBApp.PowerCatagory getPc() {
return pc;
}
public float getPower_level() {
return power_level;
}
public float getLuck() {
return luck;
}
#Id private int hid;//This is the table's primary key
public void setHid(int hid) {
this.hid = hid;
}
public void setArea(PGpolygon area) {
this.area = area;
}
public void setSpower(String spower) {
this.spower = spower;
}
public void setFname(String fname) {
this.fname = fname;
}
public void setLname(String lname) {
this.lname = lname;
}
public void setPc(DBApp.PowerCatagory pc) {
this.pc = pc;
}
public void setPower_level(float power_level) {
this.power_level = power_level;
}
public void setLuck(float luck) {
this.luck = luck;
}
private PGpolygon area;
private String spower;
private String fname;
private String lname;
private DBApp.PowerCatagory pc;
private float power_level;
private float luck;
public Hero(int hid, PGpolygon area, String spower, String fname, String lname, DBApp.PowerCatagory pc, float power_level, float luck) {
this.hid = hid;
this.area = area;
this.spower = spower;
this.fname = fname;
this.lname = lname;
this.pc = pc;
this.power_level = power_level;
this.luck = luck;
}
}
HeroService class:
package com.db.services;
import com.db.entities.Hero;
import com.db.repositories.HeroRepository;
import com.db.app.DBApp;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
#Service
public class HeroService
{
private HeroRepository heroRepository = DBApp.getAppContext().getBean(HeroRepository.class);
public List<Hero> getAllHeroes()
{
List<Hero> res = new ArrayList<>();
heroRepository.findAll().forEach(res::add);
return res;
}
public void addHero(Hero hero)
{
heroRepository.save(hero);
}
public Hero getHero(int id)
{
return heroRepository.findById(id).get();
}
public void updateHero(Hero hero)
{
heroRepository.save(hero);/*If a hero with the same id
already exists in the DB then the save() function
will automatically update that same tuple.*/
}
public void deleteHero(Hero hero)
{
heroRepository.delete(hero);
}
}
HeroController class:
package com.db.controllers;
import com.db.app.DBApp;
import com.db.entities.Hero;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.db.services.HeroService;
import java.util.List;
#RestController
public class HeroController
{
private HeroService heroService = DBApp.getAppContext().getBean(HeroService.class);
#GetMapping("/hero")
public List<Hero> getAllHeroes()
{
//System.out.println(heroService.getAllHeroes());
return heroService.getAllHeroes();
}
#GetMapping("/")
public String test()
{
//System.out.println(heroService.getAllHeroes());
return "working!!!";
}
}
pom.xml file:
<?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>
<groupId>MyDBExcercise</groupId>
<artifactId>mydbexxcercise</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>2.1.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>com.aerospike</groupId>
<artifactId>spring-data-aerospike</artifactId>
<version>1.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.5</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.4.2.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
According to the console, the reason Spring can't initialize HeroController is the exception the following code causes:
private HeroService heroService = DBApp.getAppContext().getBean(HeroService.class);
I've no idea why an exception is thrown here so any help will be very appreciated. Thank you very much for your time
Move your DBApp to the com.db package.
Remove all annotations but #SpringBootApplication the other ones are implied and auto-detected
Remove the getAppContext method.
With that your DBApp class should look something like this.
package com.db;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class DBApp {
public enum PowerCatagory{SpecialPower,Weapon,Machines}
public static void main(String[] args) {
SpringApplication.run(DBApp.class,args);
}
}
Now in your HeroService and HeroController you need to use dependency injection. Best practice is to use constructor injection instead of field injection.
#Service
public class HeroService {
private final HeroRepository heroRepository;
public HeroService(HeroRepository heroRepository) {
this.heroRepository=heroRepository;
}
The HeroController
#RestController
public class HeroController {
private final HeroService heroService;
public HeroController(HeroService heroService) {
this.heroService=heroService;
}
NOTE: The #Repository annotation on the HeroRepository can be removed as it doesn't add anything.
Next your dependencies are a bit of a mess, use the dedicated spring-boot-starters to get proper and tested versions instead. You don't need the Hibernate/JPA dependency (those are included in the spring-boot-starter-data-jpa) and others need newer versions.
<?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>
<groupId>MyDBExcercise</groupId>
<artifactId>mydbexxcercise</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>2.1.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>com.aerospike</groupId>
<artifactId>spring-data-aerospike</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Below 2 changes should fix this issue. No need to get bean from App Context.
#Service
public class HeroService {
#Autowired
private HeroRepository heroRepository;
&
#RestController
public class HeroController {
#Autowired
private HeroService heroService;
& pom.xml
<?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.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>MyDBExcercise</groupId>
<artifactId>mydbexxcercise</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.aerospike</groupId>
<artifactId>spring-data-aerospike</artifactId>
<version>1.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
& application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=*****
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
I am try to access data mysql in Spring Boot.when i run application.I got this error
Error creating bean with name 'entityManagerFactory' defined in class path resource[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javassist/bytecode/ClassFile
my code is
Controller
#GetMapping(path="/add")
public #ResponseBody String addNewUser (#RequestParam String name
, #RequestParam String email) {
UserPojo n = new UserPojo();
n.setName(name);
n.setEmail(email);
userRepository.save(n);
return "Saved";
}
Service is
#Service("service")
#Transactional
public class UserService {
#Autowired
private User user;
public void addUser(UserPojo pojo) {
UserEntity userEntity = new UserEntity();
userEntity.setCustomerName(pojo.getCustomerName());
userEntity.setEmail(pojo.getEmail());
user.save(userEntity);
}
}
Dao is
public interface User extends CrudRepository<UserEntity, Integer> {
}
Entity is-
package com.example.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "customer")
public class UserEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Column
private String customerName;
#Column
private String email;
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
My Pojo
public class UserPojo {
private String customerName;
private String email;
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
My pom.xml
<?xml version="1.0" encoding="UTF-8"?>
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<groupId>com.example</groupId>
<artifactId>Test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Test</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- JPA Data (We are going to use Repositories, Entities, Hibernate, etc...) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Use MySQL Connector-J -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</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>
application.properties
spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp
server.port=8085
server.servlet.context-path=/finance
# Database
spring.datasource.url=jdbc:mysql://localhost:3306/test?
autoReconnect=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# Hibernate
hibernate.dialect: org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql: true
hibernate.hbm2ddl.auto: create
I have implemented your project. Everything going fine. I am describing step by step. I wrote my pom.xml like this
<?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>
<groupId>org.avijit</groupId>
<artifactId>bootproject</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Then I wrote my main class and created a bean for jsp page.
#SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
#Bean
public ViewResolver getViewResolver(){
InternalResourceViewResolver resolver = new
InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
}
After this i wrote Controller class like
#Autowired
UserService userService;
#RequestMapping(value="/sample", method= RequestMethod.GET)
public String sample()
{
return "sample";
}
#RequestMapping(value="/sample", method= RequestMethod.POST)
public String dosave(#RequestParam String name, #RequestParam String email)
{
UserPojo n = new UserPojo();
n.setCustomerName(name);
n.setEmail(email);
userService.addUser(n);
return "sample";
}
And edited service class
#Autowired
private User user;
public void addUser(UserPojo pojo) {
UserEntity userEntity = new UserEntity();
userEntity.setCustomerName(pojo.getCustomerName());
userEntity.setEmail(pojo.getEmail());
user.save(userEntity);
}
While copying your code I found that in controller class you made an error n.setName(name); it would be n.setCustomerName(name). And in my property file I wrote like this.
spring.datasource.url =jdbc:mysql://127.0.0.1:3306/InternDatabase
spring.datasource.username = root
spring.datasource.password = 123456
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto = update
Check updated code and let us know.
I'm working on an online tutorial, and in the step where I need to work with databases and add jpa, I cannot access it in my project.
I have successfully put the dependency in my pom.xml file, and have received no errors. I was also able to access spring jpa through my application.properties file. The problem is that when I wanted to extend CrudRepository, it wasn't being recognized...I then realized that when I went to manually import, it would not import org.springframework.data.
I have maven set to always update snapshots.
Here is my pom.xml file. I apologize for the formatting, but I couldn't get it to all appear on stackoverflow with the correct formatting from intellij:
<?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>
<groupId>com.example</groupId>
<artifactId>demo3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo3</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</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>
And my 'application.properties' file:
spring.datasource.url=***
spring.datasource.username=***
spring.datasource.password=***
spring.jpa.database=MYSQL
spring.jpa.hibernate.ddl-auto = update
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
Cheese class:
package com.example.demo.models;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
#Entity
public class Cheese {
#Id
#GeneratedValue
private int id;
#NotNull
#Size(min=3, max=20)
private String name;
#NotNull
#Size(min=1, message = "Description must not be empty")
private String description;
public Cheese(String name, String description) {
this.name = name;
this.description = description;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
CheeseDao (interface using Spring Data/CrudRepository)
package com.example.demo.models;
import com.example.demo.models.Cheese;
public class CheeseDao extends CrudRepository<Cheese, Integer> {
}
Add the Annotation to your DAO and it should be interface not class,
#Repository
public interface CheeseDao extends JpaRepository<Cheese, Integer> {
}
However, I would recommend you to use JpaRepository instead of CrudRepository. For details see this stackoverflow thread.
Now you can access them from any spring annotated class like below,
#Autowired
private CheeseDao cheeseDao;
It seem like you missing hibernate entity dependency, to resolve just add dependency below
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
Replace
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
with
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
Instead of
package com.example.demo.models;
import com.example.demo.models.Cheese;
public class CheeseDao extends CrudRepository<Cheese, Integer> {
}
try
package com.example.demo.models;
import com.example.demo.models.Cheese;
public class CheeseDao extends CrudRepository<Object, Integer> {
}
The CrudRepository<> expects types.