I'm new in spring boot, I'm looking for help with this problem: I have two entities connected by a ManytoOne relationship. The entities are course and professor.
The professor Entity:
#Entity
#Table(name = "professor")
public class Professor implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long idProfessor;
private String name;
private String lastName;
private String phone;
private String mail;
#Fetch(FetchMode.JOIN)
#OneToMany(mappedBy = "professor", cascade= CascadeType.ALL)
private List<Course> courses;
public Professor() {
}
public Long getIdProfessor() {
return idProfessor;
}
public void setIdProfessor(Long idProfessor) {
this.idProfessor = idProfessor;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
}
The Course Entity:
#Entity
#Table(name = "course")
public class Course implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long idCourse;
private String title;
private String description;
#ManyToOne
#JoinColumn(name="professor_id")
private Professor professor;
#ManyToMany(mappedBy = "courses")
private List<Student> students;
public Course() {}
public Long getIdCourse() {
return idCourse;
}
public void setIdCourse(Long idCourse) {
this.idCourse = idCourse;
}
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;
}
}
I also created a rest controller to create Course and I defined POST endpoint like this:
#PostMapping(value="/create")
public Course createCourse(#RequestBody Course course) {
return courseRepo.save(course);
}
When I add a new course in postman, the course is added but it is not assigned to the corresponding professor (an existing professor in the database), "idProfessor" is always assigned to NULL. Here is an example of POST API execution in postman and the result in MySQL.
postman
mysql
Any suggestions?
Related
I have difficult to figure out to create an object in a class for jUnit test.
In my test I have : User user = new User(); , and I receive a
java.lang.reflect.InvocationTargetException cathed into
public abstract class ReflectiveCallable {
public Object run() throws Throwable {
try {
return runReflectiveCall();
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
This is my User class:
#Entity
public class User implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
private Double internalKey = (new Random()).nextDouble();
protected User() {
super();
}
public User(String firstName, String lastName) {
super();
this.firstName = firstName;
this.lastName = lastName;
}
public Long getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getInternalKey() {
return internalKey;
}
}
What is wrong? thanks
Customer entity
#Entity
#Table(name="Customer")
public class Customer {
#Id
#GeneratedValue
private Long cusId;
#Column(name="firstname")
private String firstName;
#Column(name="lastname")
private String lastName;
#Column(name="address")
private String add;
#Column(name="tel")
private int tel;
#Column(name="email")
private String email;
#Column(name="userName")
private String username;
#Column(name="password")
private String password;
#OneToMany(fetch = FetchType.EAGER, mappedBy = "customer")
#JsonManagedReference
private List<Complain> complain=new ArrayList<Complain>();
public Customer() {
super();
// TODO Auto-generated constructor stub
}
public Long getCusId() {
return cusId;
}
public void setCusId(Long cusId) {
this.cusId = cusId;
}
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 getAdd() {
return add;
}
public void setAdd(String add) {
this.add = add;
}
public int getTel() {
return tel;
}
public void setTel(int tel) {
this.tel = tel;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<Complain> getComplain() {
return complain;
}
public void setComplain(List<Complain> complain) {
this.complain = complain;
}
}
Complain Entity
#Entity
#Table(name="Complain")
public class Complain {
#Id
#GeneratedValue
private Long id;
#Column(name="repfirst")
private String repfirst;
#Column(name="replast")
private String replast;
#Column(name="warranty")
private String warranty;
#Column(name="dop")
private String purDate;
#Column(name="Nomachine")
private String Nomachine;
#Column(name="Complain")
private String Complain;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name="cus_id", referencedColumnName = "cusId")
#JsonBackReference
private Customer customer;
public Complain() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRepfirst() {
return repfirst;
}
public void setRepfirst(String repfirst) {
this.repfirst = repfirst;
}
public String getReplast() {
return replast;
}
public void setReplast(String replast) {
this.replast = replast;
}
public String getWarranty() {
return warranty;
}
public void setWarranty(String warranty) {
this.warranty = warranty;
}
public String getPurDate() {
return purDate;
}
public void setPurDate(String purDate) {
this.purDate = purDate;
}
public String getNomachine() {
return Nomachine;
}
public void setNomachine(String nomachine) {
Nomachine = nomachine;
}
public String getComplain() {
return Complain;
}
public void setComplain(String complain) {
Complain = complain;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
I want to pass data to the mysql database through the postman tool. How can I pass value for the foreign key column through the json query?
This is the method I have used in controller
#PostMapping(path="/",consumes="application/json",produces="application/json")
public void addComplain(#RequestBody Complain complain)
{
Integer id = complainService.getAllComplain().size()+1;
complain.setId(new Long(id));
complainService.createOrUpdateComplain(complain); }
After I send the request from the postman, all the data are saved except the foreign key. I think I missed something in mapping two tables.
This is my json query
{"complain":"No power",
"repfirst":"hi",
"replast":"all",
"warranty":"yes",
"purDate":"2020-02-29",
"nomachine":"6",
"tel":"46544654",
"Customer":[
{"cusId":"1"}
]
}
Database table image
Please help, Thanks in advance
{
"repfirst": "",
"replast": "",
"warranty": "",
"purDate" : "",
"Nomachine": "",
"Complain": "",
"cus_id": 1
}
That should work
"Customer":[
{"cusId":"1"}
]
This would work if you had Set<Customer> customers converted to an array in json, for example.
I have already connected my springboot to MySQL database. I want to display the username when user_id is specified in the HTTP request. e.g. http://8080/user/1 must display the name of the user with user_id 1.
The table contains attributes as:
| Integer user_id; | String username; | String fathername; | String mothername;
I have already tried this code in by Controller class but i does not seem to be working
#RequestMapping("/{userid}")
#ResponseBody
public String getById(Integer userid) {
String name="";
try {
Optional<Persondetails> persondetails=persondetailsRepository.findById(personid);
name = String.valueOf(userdetails.getName());
}
catch (Exception ex) {
return "Name not found";
}
return "The Name of the user is : " + name;
}
my repository code:
import java.util.List;
import java.util.Optional;
public interface UserdetailsRepository extends JpaRepository<Userdetails, Integer> {
public Optional<Userdetails> findById(Integer userid);
}
It says getName() is undefined for the type Optional
But i have defined it in Userdetails class
public class Userdetails {
#Id
#GeneratedValue
#Column(name="user_id")
private Integer userid;
#Column(name="name")
private String name;
#Column (name="fathers_name")
private String fathersname;
#Column(name="mothers_name")
private String mothersname;
public Userdetails() {
}
public Integer getUserid() {
return userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
public String getName() {
return name;
}
public void setname(String name) {
this.name = name;
}
public String getFathersname() {
return fathersname;
}
public void setFathersname(String fathersname) {
this.fathersname = fathersname;
}
public void setMothersname(String mothersname) {
this.mothersname = mothersname;
}
public String getMothersname() {
return mothersname;
}
}
It's missing the method type GET, you can do by two options:
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public User findOne(#PathVariable("id") int id){
return userService.findById(id);
}
OR
#GetMapping("/{id}")
public String getString(#PathVariable("id") int id) {
return "Helloworld";
}
Spring boot Connect with Mysql and get Data.
application.properties
server.contextPath=/demo-user
spring.datasource.url=jdbc:mysql://localhost:3306/testdb
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
*Controller.Java
#RequestMapping({"/users"})
public class UserController {
#Autowired
private UserService userService;
#GetMapping(path = {"/{id}"})
public User findOne(#PathVariable("id") int id){
return userService.findById(id);
}
}
UserService.java
public interface UserService {
User findById(int id);
}
UserServiceImpl.java
#Service
public class UserServiceImpl implements UserService {
#Autowired
private UserRepository repository;
#Override
public User findById(int id) {
return repository.findOne(id);
}
}
UserRepository .java
public interface UserRepository extends Repository<User, Integer> {
User findOne(int id);
}
User.java
#Entity
#Table(name = "user")
public class User {
#Id
#Column
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column
private String firstName;
#Column
private String lastName;
#Column
private String email;
//setter and getter
}
Make request from browser or application.
http://localhost:8080/demo-user/users/1
I have 2 entities, Role and Resource. A role can have many resources.
#Entity
public class Resource {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name="firstname")
private String firstName;
#Column(name="lastname")
private String lastName;
private String email;
#ManyToOne
#JoinColumn(name="roleId", nullable = false)
private Role role;
public int getId() {
return id;
}
public void setId(int 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 getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
#Entity
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name = "rolename")
private String roleName;
#OneToMany(mappedBy = "role", cascade = CascadeType.ALL)
private List<Resource> resources;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public List<Resource> getResources() {
return resources;
}
public void setResources(List<Resource> resources) {
this.resources = resources;
}
}
I'm trying to save a Role object that has a resource in it. This is the body of my json in postman.
{
"roleName" : "Business Analyst",
"resources" : [{
"firstName" : "John",
"lastName" : "Doe",
"email" : "John#Doe.com"
}]
}
http post call in postman:
http://localhost:8080/app/admin/roles/role
Role Controller
#RestController
#RequestMapping(value="/admin/roles")
public class RoleController {
#Autowired
private RoleService roleService;
private static final Logger log = LoggerFactory.getLogger(RoleController.class);
#RequestMapping(value="/role", method = RequestMethod.POST)
public ResponseEntity<?> addRole(#RequestBody Role role, UriComponentsBuilder ucBuilder){
log.info("Adding Role {}" + role);
log.info("Adding Rolename:" + role.getRoleName());
roleService.addRole(role);
HttpHeaders headers = new HttpHeaders();
headers.setLocation(ucBuilder.path("/admin/roles/role/{id}").buildAndExpand(role.getId()).toUri());
return new ResponseEntity<String> (headers,HttpStatus.CREATED);
}
#RequestMapping(value="role", method = RequestMethod.GET)
public ResponseEntity<List<Role>> listAllRoles(){
List<Role> roles = roleService.getAllRoles();
return new ResponseEntity<List<Role>>(roles, HttpStatus.OK);
}
}
RoleRepository
public interface RoleRepository extends CrudRepository<Role, Integer> {
}
RoleService
public interface RoleService {
public void addRole(Role role);
}
RoleServiceImpl
#Service
public class RoleServiceImpl implements RoleService {
#Autowired
private RoleRepository roleRepository;
#Override
public void addRole(Role role) {
roleRepository.save(role);
}
}
Whats happening is, the role Business Analyst gets save in the roleName field of Role table. The id of the said row is auto generated. At the same time, the resource with firstName = John, lastName = Doe and email = John#Doe.com gets save in the Resource table.
However, the role_id is not being saved automatically in the Resource table so now it is null ( the table Resource has the role_id set to nullable ). I was expecting that when I do the json post, the data will be automatically saved in the Role table and also the Resource table. Both of these are happening except that the role_id is not being saved. What did I miss?
Change addRole like below :
public void addRole(Role role) {
for(Resource resource: role.getResources()){
resource.setRole(role);
}
roleRepository.save(role);
}
I used Eclipselink MOXy to convert my POJO(using JPA) to json. and it's work.
but i have one problem. I have pojo class MAccount contain many to one relation to class MProduct,. when I convert to json, result show that class MAccount not in class MProduct.
here my class MAccount implementation:
#XmlRootElement
#Entity
#Table(name="m_account")
public class MAccount extends BaseObject implements Serializable {
private static final long serialVersionUID = UUID.randomUUID().getMostSignificantBits();
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#XmlID
private Long id;
#Column(name="account_id")
private String accountId;
#Column(name="card_number")
private String cardNumber;
//bi-directional many-to-one association to Product
#ManyToOne
#JoinColumn(name="m_product_id")
#XmlIDREF
private MProduct mProduct;
public MCustomerAccount() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getAccountId() {
return this.accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public MProduct getMProduct() {
return this.mProduct;
}
public void setMProduct(MProduct mProduct) {
this.mProduct = mProduct;
}
// Imlement base object method
...
}
here my class MProduct implementation:
#XmlRootElement
#Entity
#Table(name="m_product")
public class MProduct extends BaseObject implements Serializable {
private static final long serialVersionUID = UUID.randomUUID().getMostSignificantBits();
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#XmlID
private Long id;
#Column(name="product_code")
private String productCode;
#Column(name="product_name")
private String productName;
//bi-directional many-to-one association to MAccount
#OneToMany(mappedBy="mProduct")
#XmlInverseReference(mappedBy="mProduct")
private Set<MAccount> mAccountList;
public MProduct() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getProductCode() {
return this.productCode;
}
public void setProductCode(String productCode) {
this.productCode = productCode;
}
public String getProductName() {
return this.productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Set<MAccount> getMAccountList() {
return this.mAccountList;
}
public void setMAccountList(Set<MAccount> mAccountList) {
this.mAccountList = mAccountList;
}
// Imlement base object method
...
}
And generate JSON from MAccount class
{"MAccount":[
{"#type":"mAccount","id":"6","accountId":"05866039901"},
{"#type":"mAccount","id":"7","accountId":"25600036290"}]
}
there is no MProduct in there, the correct json result should be like below
{"MAccount":[
{"#type":"mAccount","id":6,"accountId":"05866039901","MProduct":{"#type":"mProduct","productCode":"T01","productName":"Book"}},
{"#type":"mAccount","id":7,"accountId":"25600036290","MProduct":{"#type":"mProduct","productCode":"T02","productName":"Pen"}}]
}
Is Anyone know how to solve this problem
Thank's b4
Because you are annotating the field, there is a chance that JPA has not populated that field yet due to lazy loading. If you annotate the property (get/set) instead do you still see this behaviour?
For more information on #XmlInverseReference see:
http://bdoughan.blogspot.com/2010/07/jpa-entities-to-xml-bidirectional.html