简体   繁体   中英

Spring Boot REST API gives empty rows

I am new to Spring boot. I have a MYSQL table "customer" with data as shown: Data in the table When testing the API output using Postman, there seems to be rows of empty JSON output.

API Output

Below is my code:

package com.semika.customer;

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 Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

    @Column(name="address")
    private String address;

    public Customer() {
       super();

    }

}

CustomerRepository

package com.semika.customer;

import org.springframework.data.repository.CrudRepository;

public interface CustomerRepository extends CrudRepository<Customer, Long>{

}

CustomerService

package com.semika.customer;

public interface CustomerService {
    public Iterable<Customer> findAll(); 
}

CustomerServiceImpl

package com.semika.customer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CustomerServiceImpl implements CustomerService{

    @Autowired
    private CustomerRepository customerRepository;

    public Iterable<Customer> findAll() {
        return customerRepository.findAll(); 
    }
}

CustomerController

package com.semika.customer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CustomerController {
    @Autowired
    private CustomerService  customerService;

    @RequestMapping("/customers") 
    @ResponseBody
    public Iterable<Customer> findAll() {
       Iterable<Customer> customers = customerService.findAll();
       return customers;
    }
}

I don't know what else I need to modify in the controller to be able to see the output with data.

At first look your code seems fine. So, I copied your code and try to run it and got an empty response just like you. After spending some time I figured out the reason why.

Use getter and setter in you customer class and recompile the code.

It will solve your problem. Also do the following changes:

1) Annotate CustomerRepository with @Repository
2) use @EnableJpaRepositories("package path") in your application's main class if your repository is not in the same or sub package.
3) use method type or @GetMapping annotation in your controller.

For your convenience I am writing your code after all the modifications:

TestDemoApplication.java

    package testdemo;

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

    @SpringBootApplication
    @EnableJpaRepositories("put repository path here")
    public class TestDemoApplication {

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

CustomerServiceImpl.java

package testdemo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CustomerServiceImpl implements CustomerService{

    @Autowired
    private CustomerRepository customerRepository;

    public Iterable<Customer> findAll() {
        return customerRepository.findAll(); 
    }
}

CustomerService.java

package testdemo;

public interface CustomerService {
    public Iterable<Customer> findAll(); 
}

CustomerRepository.java

package testdemo;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CustomerRepository extends CrudRepository<Customer, Long>{

}

CustomerController.java

package testdemo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CustomerController {

    @Autowired
    private CustomerService  customerService;

    @GetMapping(value = "/customers") 
     public Iterable<Customer> findAll() {
       Iterable<Customer> customers = customerService.findAll();
       return customers;
    }
}

Customer.java

package testdemo;

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 Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

    @Column(name="address")
    private String address;

    public Customer() {
       super();

    }

    public Long getId() {
        return id;
    }

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

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

Also, CrudRepository returns a Iterable<> in findAll(). It is the JpaRepository which returns List<> so, no worries about it.

You have used Iterable<Customer> . Please use List<Customer> instead of Iterable<Customer> everywhere.

You may need to iterate over the dataset and add the results to a List or as Vishal stated, change your interfaces and implementations to return a List rather than an Iterable .

package com.semika.customer;

import java.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
public class CustomerController {
    @Autowired
    private CustomerService  customerService;

    @RequestMapping("/customers") 
    @ResponseBody
    public Iterable<Customer> findAll() {
        List<Customer> results = new ArrayList<>();
        Iterator<Customer> iter = customerService.findAll().iterator();
        while (iter.hasNext()) results.add(iter.next());
        return results;
    }
}

In the following post , Andy states,

While a List is guaranteed to be an Iterable an Iterable may not be a List . This means that if you do cast an Iterable to a List it may fail at runtime. Even if it works, there's no guarantee that it will continue to work in the future as it could change in new versions of Spring Data JPA without breaking the interface's contract.

Instead of using a cast, you should declare your own query methods that return List .

Also noted in that post, you can use JpaRepository rather than CrudRepository because JPA will return a List rather than an Iterable as mentioned here .

I am new to Spring boot. I have a MYSQL table "customer" with data as shown: Data in the table When testing the API output using Postman, there seems to be rows of empty JSON output.

API Output

Below is my code:

package com.semika.customer;

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 Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

    @Column(name="address")
    private String address;

    public Customer() {
       super();

    }

}

CustomerRepository

package com.semika.customer;

import org.springframework.data.repository.CrudRepository;

public interface CustomerRepository extends CrudRepository<Customer, Long>{

}

CustomerService

package com.semika.customer;

public interface CustomerService {
    public Iterable<Customer> findAll(); 
}

CustomerServiceImpl

package com.semika.customer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CustomerServiceImpl implements CustomerService{

    @Autowired
    private CustomerRepository customerRepository;

    public Iterable<Customer> findAll() {
        return customerRepository.findAll(); 
    }
}

CustomerController

package com.semika.customer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CustomerController {
    @Autowired
    private CustomerService  customerService;

    @RequestMapping("/customers") 
    @ResponseBody
    public Iterable<Customer> findAll() {
       Iterable<Customer> customers = customerService.findAll();
       return customers;
    }
}

I don't know what else I need to modify in the controller to be able to see the output with data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM