mirror of
https://github.com/Example-uPagge/spring-boot-one-to-many.git
synced 2024-06-14 11:22:31 +03:00
Initial commit
This commit is contained in:
commit
41af59a122
33
.gitignore
vendored
Normal file
33
.gitignore
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
HELP.md
|
||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
52
pom.xml
Normal file
52
pom.xml
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?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.6.2</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.yapract</groupId>
|
||||||
|
<artifactId>spring-boot-one-to-many</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>spring-boot-one-to-many</name>
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>42.4.0</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</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>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.yprac.spring.hibernate.onetomany;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class SpringBootOneToManyApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SpringBootOneToManyApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
package com.yprac.spring.hibernate.onetomany.controller;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.yprac.spring.hibernate.onetomany.exception.ResourceNotFoundException;
|
||||||
|
import com.yprac.spring.hibernate.onetomany.repository.CommentRepository;
|
||||||
|
import com.yprac.spring.hibernate.onetomany.repository.TutorialRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.yprac.spring.hibernate.onetomany.model.Comment;
|
||||||
|
|
||||||
|
@CrossOrigin(origins = "http://localhost:8081")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api")
|
||||||
|
public class CommentController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TutorialRepository tutorialRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CommentRepository commentRepository;
|
||||||
|
|
||||||
|
@GetMapping("/tutorials/{tutorialId}/comments")
|
||||||
|
public ResponseEntity<List<Comment>> getAllCommentsByTutorialId(@PathVariable(value = "tutorialId") Long tutorialId) {
|
||||||
|
if (!tutorialRepository.existsById(tutorialId)) {
|
||||||
|
throw new ResourceNotFoundException("Not found Tutorial with id = " + tutorialId);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Comment> comments = commentRepository.findByTutorialId(tutorialId);
|
||||||
|
return new ResponseEntity<>(comments, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/comments/{id}")
|
||||||
|
public ResponseEntity<Comment> getCommentsByTutorialId(@PathVariable(value = "id") Long id) {
|
||||||
|
Comment comment = commentRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new ResourceNotFoundException("Not found Comment with id = " + id));
|
||||||
|
|
||||||
|
return new ResponseEntity<>(comment, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/tutorials/{tutorialId}/comments")
|
||||||
|
public ResponseEntity<Comment> createComment(@PathVariable(value = "tutorialId") Long tutorialId,
|
||||||
|
@RequestBody Comment commentRequest) {
|
||||||
|
Comment comment = tutorialRepository.findById(tutorialId).map(tutorial -> {
|
||||||
|
commentRequest.setTutorial(tutorial);
|
||||||
|
return commentRepository.save(commentRequest);
|
||||||
|
}).orElseThrow(() -> new ResourceNotFoundException("Not found Tutorial with id = " + tutorialId));
|
||||||
|
|
||||||
|
return new ResponseEntity<>(comment, HttpStatus.CREATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/comments/{id}")
|
||||||
|
public ResponseEntity<Comment> updateComment(@PathVariable("id") long id, @RequestBody Comment commentRequest) {
|
||||||
|
Comment comment = commentRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new ResourceNotFoundException("CommentId " + id + "not found"));
|
||||||
|
|
||||||
|
comment.setContent(commentRequest.getContent());
|
||||||
|
|
||||||
|
return new ResponseEntity<>(commentRepository.save(comment), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/comments/{id}")
|
||||||
|
public ResponseEntity<HttpStatus> deleteComment(@PathVariable("id") long id) {
|
||||||
|
commentRepository.deleteById(id);
|
||||||
|
|
||||||
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/tutorials/{tutorialId}/comments")
|
||||||
|
public ResponseEntity<List<Comment>> deleteAllCommentsOfTutorial(@PathVariable(value = "tutorialId") Long tutorialId) {
|
||||||
|
if (!tutorialRepository.existsById(tutorialId)) {
|
||||||
|
throw new ResourceNotFoundException("Not found Tutorial with id = " + tutorialId);
|
||||||
|
}
|
||||||
|
|
||||||
|
commentRepository.deleteByTutorialId(tutorialId);
|
||||||
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
package com.yprac.spring.hibernate.onetomany.controller;
|
||||||
|
import com.yprac.spring.hibernate.onetomany.exception.ResourceNotFoundException;
|
||||||
|
import com.yprac.spring.hibernate.onetomany.model.Tag;
|
||||||
|
import com.yprac.spring.hibernate.onetomany.model.Tutorial;
|
||||||
|
import com.yprac.spring.hibernate.onetomany.repository.TagRepository;
|
||||||
|
import com.yprac.spring.hibernate.onetomany.repository.TutorialRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@CrossOrigin(origins = "http://localhost:8081")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api")
|
||||||
|
public class TagController {
|
||||||
|
@Autowired
|
||||||
|
private TutorialRepository tutorialRepository;
|
||||||
|
@Autowired
|
||||||
|
private TagRepository tagRepository;
|
||||||
|
|
||||||
|
@GetMapping("/tags")
|
||||||
|
public ResponseEntity<List<Tag>> getAllTags() {
|
||||||
|
List<Tag> tags = new ArrayList<Tag>();
|
||||||
|
tagRepository.findAll().forEach(tags::add);
|
||||||
|
if (tags.isEmpty()) {
|
||||||
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||||
|
}
|
||||||
|
return new ResponseEntity<>(tags, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/tutorials/{tutorialId}/tags")
|
||||||
|
public ResponseEntity<List<Tag>> getAllTagsByTutorialId(@PathVariable(value = "tutorialId") Long tutorialId) {
|
||||||
|
if (!tutorialRepository.existsById(tutorialId)) {
|
||||||
|
throw new ResourceNotFoundException("Not found Tutorial with id = " + tutorialId);
|
||||||
|
}
|
||||||
|
List<Tag> tags = tagRepository.findTagsByTutorialsId(tutorialId);
|
||||||
|
return new ResponseEntity<>(tags, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/tags/{id}")
|
||||||
|
public ResponseEntity<Tag> getTagsById(@PathVariable(value = "id") Long id) {
|
||||||
|
Tag tag = tagRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new ResourceNotFoundException("Not found Tag with id = " + id));
|
||||||
|
return new ResponseEntity<>(tag, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/tags/{tagId}/tutorials")
|
||||||
|
public ResponseEntity<List<Tutorial>> getAllTutorialsByTagId(@PathVariable(value = "tagId") Long tagId) {
|
||||||
|
if (!tagRepository.existsById(tagId)) {
|
||||||
|
throw new ResourceNotFoundException("Not found Tag with id = " + tagId);
|
||||||
|
}
|
||||||
|
List<Tutorial> tutorials = tutorialRepository.findTutorialsByTagsId(tagId);
|
||||||
|
return new ResponseEntity<>(tutorials, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/tutorials/{tutorialId}/tags")
|
||||||
|
public ResponseEntity<Tag> addTag(@PathVariable(value = "tutorialId") Long tutorialId, @RequestBody Tag tagRequest) {
|
||||||
|
Tag tag = tutorialRepository.findById(tutorialId).map(tutorial -> {
|
||||||
|
long tagId = tagRequest.getId();
|
||||||
|
|
||||||
|
// tag is existed
|
||||||
|
if (tagId != 0L) {
|
||||||
|
Tag _tag = tagRepository.findById(tagId)
|
||||||
|
.orElseThrow(() -> new ResourceNotFoundException("Not found Tag with id = " + tagId));
|
||||||
|
tutorial.addTag(_tag);
|
||||||
|
tutorialRepository.save(tutorial);
|
||||||
|
return _tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add and create new Tag
|
||||||
|
tutorial.addTag(tagRequest);
|
||||||
|
return tagRepository.save(tagRequest);
|
||||||
|
}).orElseThrow(() -> new ResourceNotFoundException("Not found Tutorial with id = " + tutorialId));
|
||||||
|
return new ResponseEntity<>(tag, HttpStatus.CREATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/tags/{id}")
|
||||||
|
public ResponseEntity<Tag> updateTag(@PathVariable("id") long id, @RequestBody Tag tagRequest) {
|
||||||
|
Tag tag = tagRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new ResourceNotFoundException("TagId " + id + "not found"));
|
||||||
|
tag.setName(tagRequest.getName());
|
||||||
|
return new ResponseEntity<>(tagRepository.save(tag), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/tutorials/{tutorialId}/tags/{tagId}")
|
||||||
|
public ResponseEntity<HttpStatus> deleteTagFromTutorial(@PathVariable(value = "tutorialId") Long tutorialId, @PathVariable(value = "tagId") Long tagId) {
|
||||||
|
Tutorial tutorial = tutorialRepository.findById(tutorialId)
|
||||||
|
.orElseThrow(() -> new ResourceNotFoundException("Not found Tutorial with id = " + tutorialId));
|
||||||
|
|
||||||
|
tutorial.removeTag(tagId);
|
||||||
|
tutorialRepository.save(tutorial);
|
||||||
|
|
||||||
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/tags/{id}")
|
||||||
|
public ResponseEntity<HttpStatus> deleteTag(@PathVariable("id") long id) {
|
||||||
|
tagRepository.deleteById(id);
|
||||||
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
package com.yprac.spring.hibernate.onetomany.controller;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.yprac.spring.hibernate.onetomany.exception.ResourceNotFoundException;
|
||||||
|
import com.yprac.spring.hibernate.onetomany.model.Tutorial;
|
||||||
|
import com.yprac.spring.hibernate.onetomany.repository.TutorialRepository;
|
||||||
|
|
||||||
|
@CrossOrigin(origins = "http://localhost:8081")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api")
|
||||||
|
public class TutorialController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
TutorialRepository tutorialRepository;
|
||||||
|
|
||||||
|
@GetMapping("/tutorials")
|
||||||
|
public ResponseEntity<List<Tutorial>> getAllTutorials(@RequestParam(required = false) String title) {
|
||||||
|
List<Tutorial> tutorials = new ArrayList<Tutorial>();
|
||||||
|
|
||||||
|
if (title == null)
|
||||||
|
tutorialRepository.findAll().forEach(tutorials::add);
|
||||||
|
else
|
||||||
|
tutorialRepository.findByTitleContaining(title).forEach(tutorials::add);
|
||||||
|
|
||||||
|
if (tutorials.isEmpty()) {
|
||||||
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResponseEntity<>(tutorials, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/tutorials/{id}")
|
||||||
|
public ResponseEntity<Tutorial> getTutorialById(@PathVariable("id") long id) {
|
||||||
|
Tutorial tutorial = tutorialRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new ResourceNotFoundException("Not found Tutorial with id = " + id));
|
||||||
|
|
||||||
|
return new ResponseEntity<>(tutorial, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/tutorials")
|
||||||
|
public ResponseEntity<Tutorial> createTutorial(@RequestBody Tutorial tutorial) {
|
||||||
|
Tutorial _tutorial = tutorialRepository.save(new Tutorial(tutorial.getTitle(), tutorial.getDescription(), true));
|
||||||
|
return new ResponseEntity<>(_tutorial, HttpStatus.CREATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/tutorials/{id}")
|
||||||
|
public ResponseEntity<Tutorial> updateTutorial(@PathVariable("id") long id, @RequestBody Tutorial tutorial) {
|
||||||
|
Tutorial _tutorial = tutorialRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new ResourceNotFoundException("Not found Tutorial with id = " + id));
|
||||||
|
|
||||||
|
_tutorial.setTitle(tutorial.getTitle());
|
||||||
|
_tutorial.setDescription(tutorial.getDescription());
|
||||||
|
_tutorial.setPublished(tutorial.isPublished());
|
||||||
|
|
||||||
|
return new ResponseEntity<>(tutorialRepository.save(_tutorial), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/tutorials/{id}")
|
||||||
|
public ResponseEntity<HttpStatus> deleteTutorial(@PathVariable("id") long id) {
|
||||||
|
tutorialRepository.deleteById(id);
|
||||||
|
|
||||||
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/tutorials")
|
||||||
|
public ResponseEntity<HttpStatus> deleteAllTutorials() {
|
||||||
|
tutorialRepository.deleteAll();
|
||||||
|
|
||||||
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/tutorials/published")
|
||||||
|
public ResponseEntity<List<Tutorial>> findByPublished() {
|
||||||
|
List<Tutorial> tutorials = tutorialRepository.findByPublished(true);
|
||||||
|
|
||||||
|
if (tutorials.isEmpty()) {
|
||||||
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResponseEntity<>(tutorials, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.yprac.spring.hibernate.onetomany.exception;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
import org.springframework.web.context.request.WebRequest;
|
||||||
|
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class ControllerExceptionHandler {
|
||||||
|
|
||||||
|
@ExceptionHandler(ResourceNotFoundException.class)
|
||||||
|
@ResponseStatus(value = HttpStatus.NOT_FOUND)
|
||||||
|
public ErrorMessage resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
|
||||||
|
ErrorMessage message = new ErrorMessage(
|
||||||
|
HttpStatus.NOT_FOUND.value(),
|
||||||
|
new Date(),
|
||||||
|
ex.getMessage(),
|
||||||
|
request.getDescription(false));
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(Exception.class)
|
||||||
|
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
|
public ErrorMessage globalExceptionHandler(Exception ex, WebRequest request) {
|
||||||
|
ErrorMessage message = new ErrorMessage(
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR.value(),
|
||||||
|
new Date(),
|
||||||
|
ex.getMessage(),
|
||||||
|
request.getDescription(false));
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.yprac.spring.hibernate.onetomany.exception;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class ErrorMessage {
|
||||||
|
private int statusCode;
|
||||||
|
private Date timestamp;
|
||||||
|
private String message;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
public ErrorMessage(int statusCode, Date timestamp, String message, String description) {
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
this.message = message;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatusCode() {
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.yprac.spring.hibernate.onetomany.exception;
|
||||||
|
|
||||||
|
public class ResourceNotFoundException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public ResourceNotFoundException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.yprac.spring.hibernate.onetomany.model;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.OnDelete;
|
||||||
|
import org.hibernate.annotations.OnDeleteAction;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "comments")
|
||||||
|
public class Comment {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "comment_generator")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "content")
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY, optional = false)
|
||||||
|
@JoinColumn(name = "tutorial_id", nullable = false)
|
||||||
|
// @OnDelete(action = OnDeleteAction.CASCADE)
|
||||||
|
@JsonIgnore
|
||||||
|
private Tutorial tutorial;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(String content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tutorial getTutorial() {
|
||||||
|
return tutorial;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTutorial(Tutorial tutorial) {
|
||||||
|
this.tutorial = tutorial;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.yprac.spring.hibernate.onetomany.model;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.persistence.*;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
@Entity
|
||||||
|
@Table(name = "tags")
|
||||||
|
public class Tag {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private long id;
|
||||||
|
@Column(name = "name")
|
||||||
|
private String name;
|
||||||
|
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "tags")
|
||||||
|
@JsonIgnore
|
||||||
|
private Set<Tutorial> tutorials = new HashSet<>();
|
||||||
|
public Tag() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
public Set<Tutorial> getTutorials() {
|
||||||
|
return tutorials;
|
||||||
|
}
|
||||||
|
public void setTutorials(Set<Tutorial> tutorials) {
|
||||||
|
this.tutorials = tutorials;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,108 @@
|
|||||||
|
package com.yprac.spring.hibernate.onetomany.model;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.OnDelete;
|
||||||
|
import org.hibernate.annotations.OnDeleteAction;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "tutorials")
|
||||||
|
public class Tutorial {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tutorial_generator")
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
@Column(name = "title")
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Column(name = "description")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Column(name = "published")
|
||||||
|
private boolean published;
|
||||||
|
|
||||||
|
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
|
||||||
|
@JoinColumn(name = "tutorial_id")
|
||||||
|
private Set<Comment> comments = new HashSet<>();
|
||||||
|
|
||||||
|
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||||
|
@JoinTable(name = "tutorial_tags",
|
||||||
|
joinColumns = { @JoinColumn(name = "tutorial_id") },
|
||||||
|
inverseJoinColumns = { @JoinColumn(name = "tag_id") })
|
||||||
|
private Set<Tag> tags = new HashSet<>();
|
||||||
|
|
||||||
|
public Tutorial() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tutorial(String title, String description, boolean published) {
|
||||||
|
this.title = title;
|
||||||
|
this.description = description;
|
||||||
|
this.published = published;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPublished() {
|
||||||
|
return published;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublished(boolean isPublished) {
|
||||||
|
this.published = isPublished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Tag> getTags() {
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTags(Set<Tag> tags) {
|
||||||
|
this.tags = tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Comment> getComments() {
|
||||||
|
return comments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setComments(Set<Comment> comments) {
|
||||||
|
this.comments = comments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Tutorial [id=" + id + ", title=" + title + ", desc=" + description + ", published=" + published + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTag(Tag tag) {
|
||||||
|
this.tags.add(tag);
|
||||||
|
tag.getTutorials().add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeTag(Long tagId) {
|
||||||
|
Tag tag = this.tags.stream().filter(t -> t.getId() == tagId).findFirst().orElse(null);
|
||||||
|
if (tag != null) {
|
||||||
|
this.tags.remove(tag);
|
||||||
|
tag.getTutorials().remove(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.yprac.spring.hibernate.onetomany.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import com.yprac.spring.hibernate.onetomany.model.Comment;
|
||||||
|
|
||||||
|
public interface CommentRepository extends JpaRepository<Comment, Long> {
|
||||||
|
List<Comment> findByTutorialId(Long postId);
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
void deleteByTutorialId(long tutorialId);
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.yprac.spring.hibernate.onetomany.repository;
|
||||||
|
|
||||||
|
import com.yprac.spring.hibernate.onetomany.model.Tag;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface TagRepository extends JpaRepository<Tag, Long> {
|
||||||
|
|
||||||
|
List<Tag> findTagsByTutorialsId(Long tutorialId);
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.yprac.spring.hibernate.onetomany.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import com.yprac.spring.hibernate.onetomany.model.Tutorial;
|
||||||
|
|
||||||
|
public interface TutorialRepository extends JpaRepository<Tutorial, Long> {
|
||||||
|
List<Tutorial> findByPublished(boolean published);
|
||||||
|
|
||||||
|
List<Tutorial> findByTitleContaining(String title);
|
||||||
|
|
||||||
|
List<Tutorial> findTutorialsByTagsId(Long tagId);
|
||||||
|
}
|
11
src/main/resources/application.properties
Normal file
11
src/main/resources/application.properties
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
spring.datasource.url=
|
||||||
|
spring.datasource.username=
|
||||||
|
spring.datasource.password=
|
||||||
|
|
||||||
|
spring.jpa.show-sql=true
|
||||||
|
#spring.jpa.properties.hibernate.format_sql=true
|
||||||
|
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.PostgreSQL9Dialect
|
||||||
|
#spring.jpa.generate.ddl=true
|
||||||
|
spring.jpa.hibernate.ddl-auto=none
|
||||||
|
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.yprac.spring.hibernate.onetomany;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class SpringBootOneToManyApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user