Is there a way to use Resorces both as root and as sub-resource?
I want to call my api endpoint this way:
GET /persons/{id}/cars # get all cars for a person
GET /cars # get all cars
How to implement my resources to use this url schema?
Person resource:
#Path("persons")
public class PersonsResource {
#GET
#Path("{id}/cars")
public CarsResource getPersonCars(#PathParam("id") long personId) {
return new CarsResource(personId);
}
}
Cars resource:
#Path("cars")
public class CarsResource {
private Person person;
public CarsResource(long personId) {
this.person = findPersonById(personId);
}
#GET
public List<Car> getAllCars() {
// ...
}
#GET
public List<Cars> getPersonCars() {
return this.person.getCars();
}
}
You don't do it that way, instead you inject an instance of CarsResource into PersonsResource', and then you call the method ofgetPersonCars`, as follows
#Path("persons")
public class PersonsResource {
#inject
private CarsResource carsResource;
#GET
#Path("{id}/cars")
public List<Cars> getPersonCars(#PathParam("id") long personId) {
return carsResource.getPersonCars(personId);
}
}
#Path("cars")
public class CarsResource {
#GET
#Path("all")
public List<Car> getAllCars() {
// ...
}
public List<Cars> getPersonCars(long personId) {
Person person = findPersonById(personId);
return person.getCars();
}
}
Related
I'm trying to do an application using Spring Boot MVC and I've run into a problem. For the Post and Put methods I receive status 200 ok but the values are "null". The new registration on database is created but just the Id (autoincrement) column is populated and received in Postman response. Could someone help me please?
` #RequestMapping("/api")
#RestController
public class ExtractedNumbersController {
private final ExtractedNumbersService extractedNumbersService;
#Autowired
public ExtractedNumbersController(ExtractedNumbersService extractedNumbersService) {
this.extractedNumbersService = extractedNumbersService;
}
#PostMapping("/addExtractedNumbers")
public ExtractedNumbers addExtractedNumbers(#RequestBody ExtractedNumbers extractedNumbers) {
return extractedNumbersService.addExtractedNumbers(extractedNumbers);
}
#GetMapping("/findAllExtractedNumbers")
public List<ExtractedNumbers> findAllActivities() {
return extractedNumbersService.findAllExtractedNumbers();
}
#GetMapping("findExtractedNumbersById/{id}")
public Optional<ExtractedNumbers> findExtractedNumbersById(#PathVariable("id") Integer id) {
return extractedNumbersService.findByIdExtractedNumbers(id);
}
#PutMapping("/updateExtractedNumbers/{id}")
public ExtractedNumbers updateProduct(#PathVariable("id") Integer id, #RequestBody ExtractedNumbers extractedNumbers) {
Optional<ExtractedNumbers> extractedNumbersFromDatabase = extractedNumbersService.findByIdExtractedNumbers(id);
if (extractedNumbersFromDatabase.isPresent()) {
extractedNumbersFromDatabase.get().setExtractedNumbers(extractedNumbers.getExtractedNumbers());
extractedNumbersFromDatabase.get().setExtractionDate(extractedNumbers.getExtractionDate());
final ExtractedNumbers updatedExtractedNumbers = extractedNumbersService.addExtractedNumbers(extractedNumbersFromDatabase.get());
return updatedExtractedNumbers;
}
return extractedNumbersService.addExtractedNumbers(extractedNumbers);
}
#DeleteMapping("/deleteExtractedNumbersById/{id}")
public void deleteExtractedNumbersById(#PathVariable("id") Integer id) {
extractedNumbersService.deleteExtractedNumbers(id);
}
}
#Data
#Table
#Entity
#AllArgsConstructor
#NoArgsConstructor
public class ExtractedNumbers {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer extractedNumbersId;
#Column
private String extractedNumbers;
#Column
private String extractionDate;
public ExtractedNumbers(String extractedNumbers, String extractionDate) {
this.extractedNumbers = extractedNumbers;
this.extractionDate = extractionDate;
}
public String getExtractedNumbers() {
return extractedNumbers;
}
public void setExtractedNumbers(String extractedNumbers) {
this.extractedNumbers = extractedNumbers;
}
public String getExtractionDate() {
return extractionDate;
}
public void setExtractionDate(String extractionDate) {
this.extractionDate = extractionDate;
}
}
public interface ExtractedNumbersService {
List<ExtractedNumbers> findAllExtractedNumbers();
ExtractedNumbers addExtractedNumbers(ExtractedNumbers extractedNumbers);
Optional<ExtractedNumbers> findByIdExtractedNumbers(Integer extractedNumbersId);
ExtractedNumbers update(ExtractedNumbers extractedNumbers);
void deleteExtractedNumbers(Integer extractedNumbersId);
}
#Service
public class ExtractedNumbersServiceImpl implements ExtractedNumbersService {
private final ExtractedNumbersRepository extractedNumbersRepository;
public ExtractedNumbersServiceImpl(ExtractedNumbersRepository extractedNumbersRepository) {
this.extractedNumbersRepository = extractedNumbersRepository;
}
#Override
public List<ExtractedNumbers> findAllExtractedNumbers() { return extractedNumbersRepository.findAll() ; }
#Override
public ExtractedNumbers addExtractedNumbers(ExtractedNumbers extractedNumbers) {
return extractedNumbersRepository.save(extractedNumbers);
}
#Override
public Optional<ExtractedNumbers> findByIdExtractedNumbers(Integer extractedNumbersId) {
return extractedNumbersRepository.findById(extractedNumbersId);
}
#Override
public ExtractedNumbers update(ExtractedNumbers extractedNumbers) {
return extractedNumbersRepository.save(extractedNumbers);
}
#Override
public void deleteExtractedNumbers(Integer extractedNumbersId) {
extractedNumbersRepository.deleteById(extractedNumbersId);
}
}`
[Database][1]
Postman
Extracted Numbers Class
Are your attributes in ExtractedNumbers consistent with the database table column?
if your table column is like extracted_numbers you need to do the underline to camel
i am creating a simple spring boot project when i run the project ran into the problem with Spring Boot Ambiguous mapping. Cannot map method. i have create two various controller those are student and course controller.i completly attached the error below.
i attached the full
**gub link here** https://github.com/raguram1986/SpringSecuritys
Full Error i attached below
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'studentController' method
com.example.studentmanagement.Controller.StudentController#saveStudent(Student)
to {POST [/save]}: There is already 'courseController' bean method
com.example.studentmanagement.Controller.CourseController#saveCourse(Course) mapped.
Controller
#Controller
public class StudentController {
#Autowired
private StudentService service;
#GetMapping("/Student")
public String viewHomePage(Model model) {
List<Student> liststudent = service.listAll();
// model.addAttribute("liststudent", liststudent);
System.out.print("Get / ");
return "Student";
}
#GetMapping("/addStudent")
public String add(Model model) {
List<Student> liststudent = service.listAll();
model.addAttribute("liststudent", liststudent);
model.addAttribute("student", new Student());
return "addstudent";
}
#RequestMapping(value = "/save", method = RequestMethod.POST)
public String saveStudent(#ModelAttribute("student") Student std) {
service.save(std);
return "Student";
}
#RequestMapping("/edit/{id}")
public ModelAndView showEditStudentPage(#PathVariable(name = "id") int id) {
ModelAndView mav = new ModelAndView("addstudent");
Student std = service.get(id);
mav.addObject("student", std);
return mav;
}
#RequestMapping("/delete/{id}")
public String deleteStudentPage(#PathVariable(name = "id") int id) {
service.delete(id);
return "Student";
}
Student
#Entity
public class Student {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
private String stname;
private String course;
private int fee;
public Student() {
}
public Student(Long id, String stname, String course, int fee) {
this.id = id;
this.stname = stname;
this.course = course;
this.fee = fee;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getStname() {
return stname;
}
public void setStname(String stname) {
this.stname = stname;
}
public String getCourse() {
return course;
}
public void setCourse(String course) {
this.course = course;
}
public int getFee() {
return fee;
}
public void setFee(int fee) {
this.fee = fee;
}
StudentRepository
#Repository
public interface StudentRepository extends JpaRepository<Student, Long>{
}
Service
#Service
public class StudentService
{
#Autowired
private StudentRepository repo;
public List<Student> listAll() {
return repo.findAll();
}
public void save(Student std) {
repo.save(std);
}
public Student get(long id) {
return repo.findById(id).get();
}
public void delete(long id) {
repo.deleteById(id);
}
}
In your StudentController you have the endpoint /save
#RequestMapping(value = "/save", method = RequestMethod.POST)
public String saveStudent(#ModelAttribute("student") Student std) {
service.save(std);
return "Student";
}
But you haven't included the CourseController class in your question, which is mentioned in the error.
If you have defined an endpoint /save in that CourseController, then you have to rename it. Otherwise, when you invoke /save which controller needs to be invoked cannot be determined.
Add #RequestMapping above StudentController as below
#Controller
#RequestMapping("/students")
public class StudentController {
...
}
You are getting exception because there is already a mapping defined for path
/save
without being any controller mapping, so the first with root mapping is considered, but the next time it encounters same mapping it is already registered hence it is complaining. For clarity i'd suggest to add #RequestMapping to CourseController as well.
So now your course controller also becomes:
#Controller
#RequestMapping("/courses")
public class CourseController {
...
}
The best practice is to always add a request mapping at class level as well, like in your case, add a mapping like "/students" for SutdentController and "/course" for CourseController itself and then all other methods will be under that i.e. "/student/save" and then you will not face this issue anymore.
My professor gave a sample Spring MVC ORM project with Hibernate but I can not figure out the sequence of events involved, in particular about the usage of service business object.
This is just a little part of the project, just to make my ideas clearer.
domain:
#Entity
#Table(name = "department")
public class Department implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Long uid;
private String name;
#OneToMany(mappedBy="department",cascade=CascadeType.PERSIST)
private List<Employee> employees = new ArrayList<Employee>();
public Department() {
}
public Department(String name) {
this.name = name;
}
// getters, setters, hashcode() and equals(), toString()...
controller:
#Controller
#RequestMapping("/department")
public class DepartmentController {
#Autowired
#Qualifier("departmentBO")
private DepartmentBO departmentBO;
static final Logger logger = Logger.getLogger(DepartmentController.class);
#RequestMapping(value = "/home", method = RequestMethod.GET)
public String departmentHome(Model model) {
logger.debug("department home() invoked");
List<Department> list = departmentBO.findAllDepartments();
model.addAttribute("list", list);
return "departments";
}
// i'll paste just the first controller ;)
business:
public interface DepartmentBO {
public void delete(long uid);
public List<Department> findAllDepartments();
public Department findByUid(Long uid);
public void save(Department department);
public void update(Department department);
}
business/impl:
#Service
#Transactional
public class DepartmentBoImpl implements DepartmentBO {
#Autowired
private DepartmentDAO departmentDao;
static final Logger logger = Logger.getLogger(DepartmentBoImpl.class);
#Override
public void save(Department department) {
departmentDao.save(department);
}
#Override
public void update(Department department) {
departmentDao.update(department);
}
#Override
public void delete(long uid) {
departmentDao.delete(uid);
}
#Override
public List<Department> findAllDepartments() {
return departmentDao.findAllDepartments();
}
#Override
public Department findByUid(Long uid) throws DataAccessException {
return departmentDao.findByUid(uid);
}
}
dao:
public interface DepartmentDAO {
public void delete(long uid);
public List<Department> findAllDepartments();
public Department findByUid(Long uid);
public void save(Department user);
public void update(Department user);
}
dao/impl:
#Repository
public class DepartmentDAOImplSf implements DepartmentDAO {
#Autowired
private SessionFactory sessionFactory;
#Override
public void delete(long uid) {
Department department = (Department) sessionFactory.getCurrentSession()
.get(Department.class, uid);
sessionFactory.getCurrentSession().delete(department);
}
#Override
public void save(Department department) {
sessionFactory.getCurrentSession().save(department);
}
#Override
public void update(Department department) {
sessionFactory.getCurrentSession().saveOrUpdate(department);
}
#Override
public List<Department> findAllDepartments() {
List<Department> list = (List<Department>) sessionFactory
.getCurrentSession()
.createQuery("FROM Department").list();
return list;
}
#Override
public Department findByUid(Long uid) {
Department department = (Department) sessionFactory
.getCurrentSession().get(Department.class, uid);
return department;
}
}
I know that the order is: domain model -> controller-> service -> dao ->db, but why use a DepartmentBO? and why DepartmentBoImpl autowired DepartmentDao? Who of them act first? Something that i'm not understanding is messing up my conception of how it works and the sequence of the process..
Thanks for your help ;)
EDIT: "
In few words my question is, what is the sequence of this code? user goes on the /home page that redirect on "departments" page. But what happen before this --> "List list = departmentBO.findAllDepartments();" ?;)
When the departmentBO.findAllDepartments() method is called if you look at the code it invokes the sessionFactory. That is an internal factory class in Hibernate that basically builds a transactional connection to the DB in order to run a query. You are defining the query in the createQuery method and then ultimately executing it with the list() method. These two methods are part of the database session that Hibernate has instantiated.
Departments Page -> departmentBO.findAllDepartments() -> sessionFactory -> createQuery -> list()
Or in pseudo code-ish
Departments Page -> execute findAllDepartments method -> fetch / build a database connection -> define the query -> execute the query -> Return the list!
I am learning Play Framework and I need to bind Address to Person from web form.
There are my entities:
#Entity
#Table(name = "address")
public class Address {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;
private String country;
#OneToMany(mappedBy = "address", fetch = FetchType.EAGER)
private List<Person> persons;
// get/set
}
#Entity
#Table(name = "person")
public class Person {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;
private String name;
#ManyToOne(fetch = FetchType.EAGER)
private Address address;
// get/set
}
I have folllowing controller and dao:
public class HomeController extends Controller {
#Inject
private Configuration configuration;
#Inject
private PersonManager personManager;
#Inject
private AddressManager addressManager;
#Inject
FormFactory formFactory;
#Inject
Formatters formatters;
#Transactional
public Result index() {
List<Person> persons = personManager.findAll();
List<Address> addresses = addressManager.findAll();
return ok(index.render("Hello, world", persons, addresses));
}
#Transactional
public Result addPerson() {
DynamicForm requestData = formFactory.form().bindFromRequest();
System.out.println("form: " + requestData.get("address"));
Person person = Form.form(Person.class).bindFromRequest().get();
personManager.save(person);
return redirect(routes.HomeController.index());
}
#Transactional
public Result addAddress() {
Address address = Form.form(Address.class).bindFromRequest().get();
addressManager.save(address);
return redirect(routes.HomeController.index());
}
// ...
}
package dao;
public class PersonDaoImpl implements PersonDao {
#Inject
private JPAApi jpaApi;
#Override
public void save(Person user) {
jpaApi.em().persist(user);
}
#Override
public void delete(Person user) {
jpaApi.em().remove(user);
}
#Override
public void update(Person user) {
jpaApi.em().merge(user);
}
#Override
public List<Person> findAll() {
return jpaApi.em().createQuery("from Person").getResultList();
}
#Override
public Person findById(int id) {
return (Person) jpaApi.em().find(Person.class, id);
}
#Override
public Person findByName(String name) {
return (Person) jpaApi.em().createQuery("SELECT p FROM Person p WHERE p.name LIKE :name").setParameter("name", name).getSingleResult();
}
}
package dao;
public class AddreessDaoImpl implements AddressDao {
#Inject
private JPAApi jpaApi;
#Override
public void save(Address address) {
jpaApi.em().persist(address);
}
#Override
public void delete(Address address) {
jpaApi.em().remove(address);
}
#Override
public void update(Address address) {
jpaApi.em().merge(address);
}
#Override
public List<Address> findAll() {
return jpaApi.em().createQuery("from Address").getResultList();
}
#Override
public Address findById(int id) {
return (Address) jpaApi.em().find(Address.class, id);
}
#Override
public Address findByCountry(String name) {
return (Address) jpaApi.em().createQuery("SELECT a FROM Address a WHERE a.country LIKE :country").setParameter("country", name).getSingleResult();
}
}
View:
#(message: String, persons: List[Person], addresses: List[Address])
#main("Welcome to Play") {
<form action="#routes.HomeController.addPerson()" method="post">
<input type="text" name="name" />
<select name="address">
#for(address <- addresses) {
<option value="#address.getId">
#address.getCountry
</option>
}
</select>
<button>Add Person</button>
</form>
}
I need to add new person with existing Address. I'm trying to bind address to person using Formatters:
package service;
import dao.AddressManager;
import models.Address;
import play.data.format.Formatters;
import play.i18n.MessagesApi;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import java.text.ParseException;
import java.util.Locale;
#Singleton
public class FormattersProvider implements Provider<Formatters> {
private final MessagesApi messagesApi;
#Inject
public FormattersProvider(MessagesApi messagesApi) {
this.messagesApi = messagesApi;
}
#Inject
private AddressManager addressManager;
#Override
public Formatters get() {
Formatters formatters = new Formatters(messagesApi);
formatters.register(Address.class, new Formatters.SimpleFormatter<Address>(){
#Override
public Address parse(String input, Locale locale) throws ParseException {
Address address = addressManager.findById(Integer.getInteger(input));
return address;
}
#Override
public String print(Address address, Locale locale) {
return address.getCountry();
}
});
return formatters;
}
}
package service;
import com.google.inject.AbstractModule;
import play.data.format.Formatters;
public class FormattersModule extends AbstractModule {
#Override
protected void configure() {
bind(Formatters.class).toProvider(FormattersProvider.class);
}
}
But how can I use Formatters?
If I add address, it is ok.
But if I add new Person using web form address column in db have NULL value, or app crash:
[error] application -
! #720fgnbfl - Internal server error, for (POST) [/person] ->
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[CompletionException: java.lang.IllegalStateException: Error(s) binding form: {"address":["Invalid value"]}]]
at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:280)
at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:206)
at play.api.GlobalSettings$class.onError(GlobalSettings.scala:160)
at play.api.DefaultGlobal$.onError(GlobalSettings.scala:188)
at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:98)
at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:100)
at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:99)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:344)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:343)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
Caused by: java.util.concurrent.CompletionException: java.lang.IllegalStateException: Error(s) binding form: {"address":["Invalid value"]}
at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:292)
at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:308)
at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:593)
at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:577)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474)
at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1977)
at scala.concurrent.java8.FuturesConvertersImpl$CF.apply(FutureConvertersImpl.scala:21)
at scala.concurrent.java8.FuturesConvertersImpl$CF.apply(FutureConvertersImpl.scala:18)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
at scala.concurrent.BatchingExecutor$Batch$$anonfun$run$1.processBatch$1(BatchingExecutor.scala:63)
Caused by: java.lang.IllegalStateException: Error(s) binding form: {"address":["Invalid value"]}
at play.data.Form.get(Form.java:634)
at controllers.HomeController.addPerson(HomeController.java:106)
at router.Routes$$anonfun$routes$1$$anonfun$applyOrElse$2$$anonfun$apply$2.apply(Routes.scala:293)
at router.Routes$$anonfun$routes$1$$anonfun$applyOrElse$2$$anonfun$apply$2.apply(Routes.scala:293)
at play.core.routing.HandlerInvokerFactory$$anon$4.resultCall(HandlerInvoker.scala:157)
at play.core.routing.HandlerInvokerFactory$$anon$4.resultCall(HandlerInvoker.scala:156)
at play.core.routing.HandlerInvokerFactory$JavaActionInvokerFactory$$anon$14$$anon$3$$anon$1.invocation(HandlerInvoker.scala:136)
at play.core.j.JavaAction$$anon$1.call(JavaAction.scala:73)
at play.http.HttpRequestHandler$1.call(HttpRequestHandler.java:54)
at play.db.jpa.TransactionalAction.lambda$call$4(TransactionalAction.java:28)
Why? How can I bind it?
Ok so I am new to spring and don't really know how this works. I have been trying a few things and think its close to doing it but not getting any data from the server and giving me this error
Unsatisfied dependency expressed through constructor argument with index 4 of type [jp.co.fusionsystems.dimare.crm.service.impl.MyDataDefaultService]: : Error creating bean with name 'MyDataDefaultService' defined in file
My end point
//mobile data endpoint
#RequestMapping(
value = API_PREFIX + ENDPOINT_MyData + "/getMyData",
method = RequestMethod.GET)
public MyData getMyData() {
return MyDataDefaultService.getData();
}
My Object
public class MyData {
public MyData(final Builder builder) {
videoLink = builder.videoLink;
}
private String videoLink;
public String getVideoLink()
{
return videoLink;
}
public static class Builder
{
private String videoLink = "";
public Builder setVideo(String videoLink)
{
this.videoLink = videoLink;
return this;
}
public MyData build()
{
return new MyData(this);
}
}
#Override
public boolean equals(final Object other) {
return ObjectUtils.equals(this, other);
}
#Override
public int hashCode() {
return ObjectUtils.hashCode(this);
}
#Override
public String toString() {
return ObjectUtils.toString(this);
}
}
The Repository
public classMyServerMyDataRepository implements MyDataRepository{
private finalMyServerMyDataJpaRepository jpaRepository;
private final MyDataConverter MyDataConverter = new MyDataConverter();
#Autowired
publicMyServerMyDataRepository(finalMyServerMyDataJpaRepository jpaRepository) {
this.jpaRepository = Validate.notNull(jpaRepository);
}
#Override
public MyData getData() {
MyDataEntity entity = jpaRepository.findOne((long) 0);
MyData.Builder builder = new MyData.Builder()
.setVideo(entity.getVideoLink());
return builder.build();
}
The DefaultService that gets called by the endpoint
public class MyDataDefaultService {
private static final Logger logger = LoggerFactory.getLogger(NotificationDefaultService.class);
private finalMyServerMyDataRepository repository;
#Autowired
public MyDataDefaultService(MyServerMyDataRepository repository) {
this.repository = Validate.notNull(repository);
}
//Get the data from the server
public MobileData getData()
{
logger.info("Get Mobile Data from the server");
//Get the data from the repository
MobileData mobileData = repository.getData();
return mobileData;
}
}
The Converter
public class MyDataConverter extends AbstractConverter<MyDataEntity, MyData>
{
#Override
public MyData convert(MyDataEntity entity) {
MyData.Builder builder = new MyData.Builder()
.setVideo(entity.getVideoLink());
return builder.build();
}
}
My Entity
#Entity
#Table(name = “myServer”)
public class MyDataEntity extends AbstractEntity{
#Column(name = "video_link", nullable = true)
private String videoLink;
public String getVideoLink() {
return videoLink;
}
public void setVideoLink(final String videoLink) {
this.videoLink = videoLink;
}
}
Thank you for any help with this
Hibernate entity should have default constructor defined and implement Serializable interface as well, assume AbstractEntity matches the requirement. Hibernate won't accept an entity without a primary key so you have to define the one too:
#Entity
#Table(name = “myServer”)
public class MyDataEntity implements Serializable {
#Id
#GeneratedValue
private Long id;
#Column(name = "video_link", nullable = true)
private String videoLink;
public MyDataEntity() {
}
...setters&getters
}
MyData object represents the JSON server response, you can use Jackson annotations to control the result JSON properties:
public class MyDataResponse {
#JsonProperty("video_link")
private String videoLink;
public MyDataResponse() {
}
public MyDataResponse(String videoLink) {
this.videoLink = videoLink;
}
...setters&getters
}
Spring has an awesome project so called Spring Data that provides the JPA repositories, so there's no even the #Repository annotation ever needed:
public class MyDataRepository extends CrudRepository<MyDataEntity, Long> {
}
The Builder class represents the Service layer:
#Service
public class MyDataService {
#Autowired
private MyDataRepository myDataRepository;
public MyDataResponse getMyData(Long id) {
MyDataEntity entity = myDataRepository.findOne(id);
...rest logic, copy necessary data to MyDataResponse
}
}
Then a controller is:
#RestController // #ResponseBody not needed when using like this
public MyDataController {
#Autowired
private MyDataService myDataService;
#RequestMapping("/getMyData") // no need to specify method for GET
public MyDataResponse getMyData(#RequestParam("ID") Long myDataId) {
... validation logic
return myDataService.getMyData(myDataId); // return response
}
}
Now it should work, don't forget to add required dependencies to your classpath.