ManyToMany Relation with Play Framework 1.2.5 JPA - jpa

I have 2 Models Article.java and Tags.java. An Article can have many Tags, and a Tags can be belonged to many Article. I am really in trouble to make this relation using JPA and Play Framework 1.2.5. Below are my codes (without setter-getter), and actually it works even throwing exception but I can not get the Tags (getTagname()) of an Article
Article article = Article.findById((long)id);
List<Tags> tags = article.getTags();
for (Tags tags2 : tags) {
System.out.println(tags2.getTagname());
}
Here is my models, Article.java
#Entity
public class Article extends Model{
#Required
public String title;
#Required
public String link;
#Required
#Lob
public String description;
public Date date;
#ManyToMany(cascade=CascadeType.ALL)
public List<Tags> tags = new ArrayList<Tags>();
}
Tags.java
#Entity
public class Tags extends Model {
#Required
public String tagname;
#ManyToMany(mappedBy="tags")
public List<Article> tagsInArticle = new ArrayList<Article>();
}

I am doing something like your code provided above (and use Play 1.2.5), and it seems there is are problems found with the code you provided. The following are my step:
First, I create 2 models Article.java
package models;
import play.data.validation.Required;
import play.db.jpa.Model;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import java.util.ArrayList;
import java.util.List;
#Entity
#Table(name = "article")
public class Article extends Model {
#Required
public String title;
#ManyToMany(cascade = CascadeType.ALL)
public List<Tag> tags = new ArrayList<Tag>();
}
and Tag.java
package models;
import play.data.validation.Required;
import play.db.jpa.Model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import java.util.ArrayList;
import java.util.List;
#Entity
#Table(name = "tag")
public class Tag extends Model {
#Required
#Column(name = "tag_name")
public String tagName;
#ManyToMany(mappedBy = "tags")
public List<Article> articles = new ArrayList<Article>();
}
Then, on the database, I manually added several record for testing purpose:
article (id;title) > 1;"java example" and 6;"article1"
tag (id;tag_name) > 4;"java" and 5;"playframework"
article_tag (articles_id;tags_id) > 6;4 and 6;5 and 1;4
So then, I testing it with the controller action :
public static void test() {
Article article = Article.findById(6L); // find "article1"
Tag tag_java = Tag.findById(4L); // find java tag
render(article, tag_java);
}
and view below:
#{extends 'main.html' /}
<h3>Article Title : ${article?.title}</h3>
Tags:<br>
<ol>
#{list article?.tags, as:'tag'}
<li>${tag.tagName}</li>
#{/list}
</ol>
All article tagged <b>java</b> :
<ul>
#{list tag_java?.articles, as:'java_article'}
<li>${java_article.title}</li>
#{/list}
</ul>
and lastly, the result is what to be expected :
UPDATE
This #ManyToOne relation is bi-directional. Providing with single data article, we can have all tag on that article, and also all of these tag can have all article data corresponding to each tag. The controller codes are similar, but without passing Tag object directly and the views look like following:
#{extends 'main.html' /}
<h3>Article Title : ${article?.title}</h3>
Tags:<br>
<ol>
#{list article?.tags, as:'tag'}
<li>${tag.tagName}</li>
#{/list}
</ol>
#{list article?.tags, as:'tag'}
Related article [tagged with ${tag.tagName}]:<br>
<ol>
#{list tag?.articles, as:'article'}
<li>${article.title}</li>
#{/list}
</ol>
#{/list}

Related

Request method 'POST' not supported, but the method for creating objects works

I create a CRUD application using SpringBoot. I use PostgreSQL as a database. My application also uses SpringSecurity. The methods of displaying and creating objects work perfectly. But for some reason, updating and deleting the same objects gives an error:
2022-11-01 08:51:14.602 WARN 12149 --- [io-8080-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
I think the problem is in the html code. I use Thymeleaf.
**My Student Controller:
**
package ru.connor.FirstSecurityApp.controllers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import ru.connor.FirstSecurityApp.model.Student;
import ru.connor.FirstSecurityApp.services.StudentService;
import javax.validation.Valid;
import java.util.Optional;
#Controller
#RequestMapping("/students")
#RequiredArgsConstructor
public class StudentController {
private final StudentService studentService;
#GetMapping()
public String showAllClasses(Model model) {
model.addAttribute("students", studentService.showAllStudent());
return "main/AllClasses";
}
#GetMapping("/{id}")
public String showById(#PathVariable("id") int id, Model model){
Optional<Student> student = Optional.ofNullable(studentService.showStudentById(id));
if (student.isEmpty()){
return "main/students/errorPage";
}else model.addAttribute("student", student);
return "main/students/index";
}
#GetMapping("/add")
public String addStudent(#ModelAttribute("student") Student student) {
return "main/students/new";
}
#PostMapping()
public String create(#ModelAttribute("student") #Valid Student student,
BindingResult bindingResult) {
if (bindingResult.hasErrors())
return "main/students/new";
studentService.addStudent(student);
return "redirect:/students";
}
#GetMapping("/{id}/edit")
public String edit(Model model, #PathVariable("id") int id) {
model.addAttribute("student", studentService.showStudentById(id));
return "main/students/edit";
}
#PatchMapping("/{id}")
public String update(#ModelAttribute("student") #Valid Student student, BindingResult bindingResult, #PathVariable("id") int id) {
if (bindingResult.hasErrors()){
return "main/students/edit";}
studentService.update(id, student);
return "redirect:/students";
}
#DeleteMapping("/{id}")
public String delete(#PathVariable("id") int id){
Optional<Student> student = Optional.ofNullable(studentService.showStudentById(id));
if (student.isPresent()){
studentService.delete(id);
return "redirect:/students";
}
return "main/students/index";
}
}
Student Service:
package ru.connor.FirstSecurityApp.services;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.connor.FirstSecurityApp.model.Student;
import ru.connor.FirstSecurityApp.repository.StudentsRepository;
import java.util.List;
import java.util.Optional;
#Service
#RequiredArgsConstructor
#SuppressWarnings("unused")
#Transactional(readOnly = true)
public class StudentService {
private final StudentsRepository studentsRepository;
public List<Student> showAllStudent(){
return studentsRepository.findAll();
}
public Student showStudentById(int id){
Optional<Student> foundPerson = studentsRepository.findById(id);
return foundPerson.orElse(null);
}
#Transactional
public void addStudent(Student student){
studentsRepository.save(student);
}
#Transactional
public void update(int id, Student person){
person.setId(id);
studentsRepository.save(person);
}
#Transactional
public boolean delete(int id){
if (studentsRepository.findById(id).isPresent()){
studentsRepository.deleteById(id);
return true;
}
return false;
}
}
**HTML view where the delete form is specified:
**
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Student</title>
</head>
<body>
<h1 th:text="${student.get().getFullStudentName()}"></h1>
<hr>
<form method="post" th:action="#{/students/{id}(id=${student.get().getId()})}">
<input type="submit" value="Delete">
</form>
</body>
</html>
As you have mentioned #PatchMapping for updates then you need the HTTP PATCH method instead of POST. The same goes for delete you have used #DeleteMapping, so you need to use the HTTP DELETE method instead of POST.
Create -> POST
Read -> GET
Update -> PUT/PATCH
Delete -> DELETE
With form submit I don't think PATCH/PUT/DELETE will work so in that case you need to change #PatchMapping/#DeleteMapping to #PostMapping and update the URL so it will be unique for update/delete.
PUT/PATCH/DELETE will work with REST API only.

I'm doing simple integration of Mongodb and springboot, but unable to save data properly

I'm fairly new to java and spring boot. I'm trying to save data in mongo through spring, but it only saves _id=0 and model class.
My controller
package com.example.usermanagement.resource;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
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.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.usermanagement.model.User;
import com.example.usermanagement.repository.userRepository;
#RestController
public class UserController {
#Autowired
private userRepository repository;
#PostMapping("/saveUser")
public String saveUser(#RequestBody User user){
System.out.println(user);
repository.save(user);
return "User Added";
}
#GetMapping("/findAllUsers")
public List<User> getUsers(){
return repository.findAll();
}
#GetMapping("/findAllUsers{id}")
public Optional<User> getUser(#PathVariable int id){
return repository.findById(id);
}
#DeleteMapping("/delete/{id}")
public String deleteUser(#PathVariable int id){
repository.deleteById(id);
return "User Deleted";
}
}
On hitting save through postman, I get this in my db
[![enter image description here][1]][1]
My model
package com.example.usermanagement.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
#Getter
#Setter
#ToString
#Document(collection = "user_data")
public class User {
#Id
private int id;
private String firstName;
private String lastName;
}
And the repository
package com.example.usermanagement.repository;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import com.example.usermanagement.model.User;
#Repository
public interface userRepository extends MongoRepository<User, Integer> {
}
I do not understand what I'm doing wrong here, Why the rest of the data is not getting saved properly also Id is coming 0 rather than what I'm sending.
Post request I'm sending
{
"id":2,
"name":"yash",
"lastName":"asd",
"role":"dev"
}
When you dont use #Field to notify to database, you need to pass the same model class name as parameters.
{
"id":2,
"firstName":"yash",
"lastName":"asd"
}
Lombok won't automatically be configured. So you need to manually configure. Setting up lombok

org.apache.openjpa.persistence.EntityExistsException: Attempt to persist detached object

The entity class is
package com.dunkul.entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="employee")
public class Book implements Serializable{
private int id;
private String name;
public Book(){
}
#Id
#Column(name="Id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Persisting is as follows
public void addBook(Book book) {
entityManager.persist(book);
}
Getting following exception
INFO: Using dictionary class
"org.apache.openjpa.jdbc.sql.MySQLDictionary" (MySQL 5.7.9-log ,MySQL
Connector Java mysql-connector-java-5.1.37 ( Revision:
09940f05b4c98150f352e787a2549f11a2e9d
a93 )).
Nov 16, 2015 2:08:03 PM null
INFO: Connected to MySQL version 5.5 using JDBC driver MySQL Connector Java version mysql-connector-java-5.1.37 ( Revision:
09940f05b4c98150f352e787a2549f11a2e9da93 ).
Nov 16, 2015 2:08:04 PM org.apache.openejb.core.transaction.EjbTransactionUtil
handleSystemException
SEVERE: EjbTransactionUtil.handleSystemException: Attempt to persist detached object "com.dunkul.entity.Book#1c7cf37d". If this is
a new instance, make sure any version and/or auto-generated
primary key fields are null/default when persisting.
org.apache.openjpa.persistence.EntityExistsException: Attempt to
persist detached object "com.dunkul.entity.Book#1c7cf37d". If this is
a
new instance, make sure any version and/or auto-generated primary key fields are null/default when persisting.
FailedObject: com.dunkul.entity.Book#1c7cf37d
at org.apache.openjpa.kernel.BrokerImpl.persistInternal(BrokerImpl.java:2659)
at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2602)
at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2585)
Please help. Table book has 2 columns .. Id and Name. Id is PK and NN
Name is VARCHAR(45). Default for Name is NULL.
There are a few issues here:
the entity name is "Book", but the table that it maps to is "employee"; not an error per se, but is it intended?
your #Id field needs to be generated somehow (which is what the exception tells you); you could start with adding an annotation #GeneratedValue(strategy=GenerationType.AUTO),
the attribute "name" of Book is not mapped (neither persisted, nor transient).

Web App Project, need assistance

Can someone please help, im in my first year of college and im stuck on my web development project. On my blog web page I have a list of posts which i need to arrange chronolgically (new post first). We just started arraylists in my programming class but we have not yet covered how to sort them
Were using the PLAY framework for the project consisting of models, controllers, views and routes. I have a Post Class in the models folder and a Blog Class in controllers shown below
package models;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import play.db.jpa.Model;
#Entity
public class Post extends Model
{
public String title;
#Lob
public String content;
#OneToMany
public List<Comment> comments = new ArrayList<Comment>();
public String comment;
public Post(String title, String content)
{
this.title = title;
this.content = content;
}
public String toString()
{
return title;
}
}
package controllers;
import java.util.List;
import models.Message;
import models.Post;
import models.User;
import play.Logger;
import play.mvc.Controller;
public class Blog extends Controller
{
public static void index()
{
User user = Accounts.getLoggedInUser();
render(user);
}
public static void newPost(String title, String content)
{
User user = Accounts.getLoggedInUser();
Post post = new Post (title, content);
post.save();
user.posts.add(post);
user.save();
Logger.info ("title:" + title + " content:" + content);
index();
}
public static void deletePost(Long postid)
{
User user = Accounts.getLoggedInUser();
Post post = Post.findById(postid);
user.posts.remove(post);
user.save();
post.delete();
index();
}
}
and this is the html code that displays the published posts
<section class="ui stacked segment">
<h4 class="ui inverted blue block header">Display Posts</h4>
#{list items:user.posts, as:'post'}
<h5 class="ui inverted green block header"></h5>
<i class="external url icon">${post.title}
#{/list}
</section>
Im totally lost in terms of the java part and have crashed the project numerous times trying to make it work, any help would be greatly appreciated

new to play! Having trouble with: Please annotate your JPA model with #javax.persistence.Entity annotation

new to play and just trying to follow the video on: http://www.playframework.org/
I'm coming so far that i want to create the list of tasks after creating the Task-class. I when i reload i get this error:
"UsupportedOperationException occured : Please annotate your JPA model with #javax.persistence.Entity annotation."
I'm using Eclipse. Also note that i have changed tasks to be persons in:
My Person model/class-defination in Person.java
package models;
import play.*;
import play.db.jpa.*;
import javax.persistence.*;
import java.util.*;
public class Person extends Model{
public String title;
public boolean done;
public Person(String title){
this.title = title;
}
}
And application.java:
package controllers;
import play.*;
import play.mvc.*;
import java.util.*;
import models.*;
public class Application extends Controller {
public static void index() {
List persons = Person.find("order by id desc").fetch();
render(persons);
}
}
The error is connected with this line:
List persons = Person.find("order by id desc").fetch();
Add #Entity to the top of the model class.
And let's be clear, use the Javax Entity annotation and not Hibernate's! As suggested in the official documentation!
As mentioned before add #Entity before your Model class.
Within your example the Person class would look like that:
package models;
import play.*;
import play.db.jpa.*;
import javax.persistence.*;
import java.util.*;
#Entity
public class Person extends Model{
public String title;
public boolean done;
public Person(String title){
this.title = title;
}
}