І am developing a REST API app with Spring Boot. I have 2 tables in the database, the first is called TblEmployees, the second is called TblDepartments. From these 2 tables I made a class Employees_DTO which should return data in JSON format. And from the TblEmployees table it will return data and from the TblDepartments table it returns null. dbID is a foreign key I did as I thought but at me it doesn't work:
public class TblDepartments {
private Integer dbID;
private String dep_name;
public class TblEmployees {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int emp_id;
private String empName;
private Boolean empActive;
private Integer dbID;
public class Employees_DTO {
private int emp_id;
private String empName;
private Boolean empActive;
private String dep_name;
}
package com.example.test_task.exceptions;
import com.example.test_task.*;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.modelmapper.spi.MatchingStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
#Service
public class EmployessServise {
#Autowired
private EmplployeesRepository repo;
#Autowired
private ModelMapper modelMapper;
public EmployessServise() {
}
public List<Employees_DTO> getAll_Emp(){
return repo.findAll()
.stream()
.map(this::convertEntityToDto)
.collect(Collectors.toList());
}
private Employees_DTO convertEntityToDto(TblEmployees tblEmployees){
modelMapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.LOOSE);
Employees_DTO employees_dto=new Employees_DTO();
employees_dto=modelMapper.map(tblEmployees,Employees_DTO.class);
return employees_dto;
}
private TblEmployees convertEntityToDto(Employees_DTO employees_dto){
modelMapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.LOOSE);
TblEmployees tblEmployees=new TblEmployees();
tblEmployees=modelMapper.map(employees_dto,TblEmployees.class);
return tblEmployees;
}
}
#ManyToOne is available:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
#Entity
public class TblEmployees {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int emp_id;
private String empName;
private Boolean empActive;
#ManyToOne
#JoinColumn(name = "dbid")
private TblDepartments department;
// Getters and Setters
}
full sample code
Related
This question is kindly related to a previous one here:
getting null while posting data
I tryed a suggested answer, imported lombok and created a DTO class as follows:
package com.example.dto;
import java.util.HashSet;
import java.util.Set;
import lombok.Data;
#Data
public class TownDTO {
public String name;
public String regionid;
}
Table towns is related to a regions table in db. While I try to save data I am getting a following exception:
not-null property references a null or transient value : com.example.model.Towns.regionid
Here is my model class
package com.example.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
#Data
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "towns")
public class Towns {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name = "name")
private String name;
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "regionid", nullable = false)
#OnDelete(action = OnDeleteAction.CASCADE)
private Regions regionid;
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;
}
public Regions getRegionid() {
return regionid;
}
public void setRegionid(Regions regionid) {
this.regionid = regionid;
}
}
And repositories are as follows.
Towns repository
package com.example.repository;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
import com.example.model.Towns;
import com.example.model.Regions;
public interface TownsRepository extends JpaRepository<Towns, Integer> {
List<Towns> findByNameContaining(String name);
Page<Regions> findByregionid(Integer regionid, Pageable pageable);
Optional<Regions> findByregionidAndId(Integer regionId, Integer id);
}
regions repository
package com.example.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.model.Regions;
public interface RegionsRepository extends JpaRepository<Regions, Integer> {
List<Regions> findByNameContaining(String name);
}
And finaly the controller method:
#PostMapping("/add")
public ResponseEntity<TownDTO> createPost(#RequestBody TownDTO townDto) {
// convert DTO to entity
Towns townRequest = modelMapper.map(townDto, Towns.class);
//System.out.println(townDto.regionid);
//System.out.println(townRequest.getName());
Towns town = townsrepository.save(townRequest);
// convert entity to DTO
TownDTO townResponse = modelMapper.map(town, TownDTO.class);
return new ResponseEntity<TownDTO>(townResponse, HttpStatus.CREATED);
}
I am able to print out townDTO.regionid and value is correct 2 in my case. But request is still null. Here is a request from postman
{
"name": "test",
"regionid": "2"
}
What am I missing right now?
Removed #jsonignore and added getters and setters to DTO
package com.example.dto;
import java.util.HashSet;
import java.util.Set;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
#Data
public class TownDTO {
public String name;
public String regionid;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRegionid() {
return regionid;
}
public void setRegionid(String regionid) {
this.regionid = regionid;
}
}
Nothin had change. Error is the same
Your TownDTO contains String regionid whereas your Model class it's Region Object. So moddlemapper can't map.
//DTO
public String regionid;
//Model
private Regions regionid;
I read many people asked the same question but I have followed all the rules, and I don't know what am I missing
I have following:
Main
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Model
package com.example.demo.model;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
#Entity
#Table(name = "ivsd_account")
public class Account implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "acc_id")
private Long accId;
#Column(name = "acc_uid", unique = true, nullable = false)
private String accUid;
#Column(name = "acc_created_by_acc_uid")
private String accCreatedByAccUid;
#CreationTimestamp
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "acc_created_date")
private Date accCreatedDate;
#Column(name = "acc_updated_by_acc_uid")
private String accUpdatedByAccUid;
#UpdateTimestamp
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "acc_updated_date")
private Date accUpdatedDate;
#UpdateTimestamp
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "acc_sync_tst")
private Date accSyncTst;
#Column(name = "acc_enabled")
private Boolean accEnabled;
#Column(name = "acc_name")
private String accName;
#Column(name = "acc_email")
private String accEmail;
#Column(name = "acc_username")
private String accUsername;
#Column(name = "acc_password")
private String accPassword;
getters and setters
DTO
package com.example.demo.dto;
import com.example.demo.model.Account;
import java.util.Date;
public class AccountDTO {
private Long accId;
private String accUid;
private String accCreatedByAccUid;
private Date accCreatedDate;
private String accUpdatedByAccUid;
private Date accUpdatedDate;
private Date accSyncTst;
private Boolean accEnabled;
private String accName;
private String accEmail;
private String accUsername;
private String accPassword;
getters and setters
Repository
package com.example.demo.repository;
import com.example.demo.model.Account;
import org.springframework.stereotype.Repository;
#Repository
public interface AccountRepository extends CustomRepository<Account, Long> {
Account findOneByAccName(String name);
Account findByAccUid(String uid);
Account findByAccEmail(String email);
void deleteAccountByAccUid(String uid);
}
Service
package com.example.demo.service;
import com.example.demo.dto.AccountDTO;
import com.example.demo.mapper.AccountMapper;
import com.example.demo.model.Account;
import com.example.demo.repository.AccountRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
#Service
public class AccountService {
#Autowired
private AccountRepository accountRepository;
#Autowired
private AccountMapper accountMapper; // Could not autowire. No beans of AccountMapper type found
#Transactional(readOnly = true)
public List<AccountDTO> loadAll() {
List<Account> res = accountRepository.findAll();
List<AccountDTO> resF = accountMapper.entitiesToDto(res);
return resF;
}
Controller
package com.example.demo.controller;
import com.example.demo.service.AccountService;
import com.example.demo.dto.AccountDTO;
import com.example.demo.system.ResponseWrapper;
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.List;
#RestController
#RequestMapping("/api")
public class AccountController {
#Autowired
private AccountService accountService;
#RequestMapping(value = "/accounts", method = RequestMethod.GET)
public ResponseEntity<?> loadAll() {
List<AccountDTO> res = accountService.loadAll();
return new ResponseEntity(new ResponseWrapper(res), HttpStatus.OK);
}
Mapper
package com.example.demo.mapper;
import com.example.demo.dto.AccountDTO;
import com.example.demo.model.Account;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.ReportingPolicy;
import java.util.List;
#Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = "spring")
public interface AccountMapper {
AccountDTO entityToDto(Account entity);
Account dtoToEntity(AccountDTO entity);
Account updateEntityFromDto(AccountDTO dto, #MappingTarget Account entity);
List<AccountDTO> entitiesToDto(List<Account> entities);
}
I get an error in Service:
Field accountMapper in com.example.demo.service.AccountService required a bean of type 'com.example.demo.mapper.AccountMapper' that could not be found.
I have placed all the classes in sub packages of the package from Main class.
If I add annotation #ComponentScan("com.example.demo.mapper") then it works only for mapper package, other packages are not scanned. Sorry for stupid question. Any help I appreciate
Thank you
Check if you have properly configured mapstruct.
Run a mvn clean install before starting the application, mapstruct will generate the mapper class that will be annotated with #Component.
Class where I create the empty constructor com lombok:
Notes.java:
package com.udacity.jwdnd.course1.cloudstorage.modelo;
import lombok.*;
import java.io.Serializable;
#Getter
#Setter
#NoArgsConstructor(access = AccessLevel.PUBLIC)
#AllArgsConstructor
public class Notes implements Serializable {
private Integer noteId;
private String noteTitle;
private String noteDescription;
private Integer userId;
public Notes(Integer noteId, String noteTitle
, String noteDescription, Integer userId) {
this.noteId = noteId;
this.noteTitle = noteTitle;
this.noteDescription = noteDescription;
this.userId = userId;
}
}
I use an object of Class Notes.java. In the following file an instance was created applying the empty constructor, but it throws me the error in the image:
import com.udacity.jwdnd.course1.cloudstorage.modelo.Notes;
import com.udacity.jwdnd.course1.cloudstorage.services.NoteService;
import com.udacity.jwdnd.course1.cloudstorage.services.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
#Controller
#RequestMapping("/home")
public class InicioController {
#Autowired
private UsersService usuarioService;
#Autowired
private NoteService notaService;
#Autowired
private CredentialService credencialService;
#Autowired
private ArchivoService archivoService;
#GetMapping()
public String irPaginaHome(Authentication auth, Model model){
model.addAttribute("noteForm", new Notes());
Integer idUsuario = usuarioService.obtenerIdusuario(auth.getName());
List<Notes> notas = notaService.notas(idUsuario);
model.addAttribute("notas",notas);
return "home";
}
}
model.addAttribute("noteForm", new Notes());
Can't find empty constructor, what would be the problem.
I am trying to do a mini-project where there is a scenario where people can add incidence and others can comment on it.But the problem is when i try to comment on a incident the old comment is getting updated with the new comment instead of creating a new record. I am using a mapping able which has incidenceId and commentId as columns.
If i am adding a comment for incidenceId=1 it is getting added and is reflected in mapping table but again if i try adding one more comment for the same incidenceId(i.e, 1) it is getting uppdated.
My IncidenceDO is
package com.incture.metrodata.entity;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
#Entity
#Table(name="INCIDENCE_DETAILS")
#Getter
#Setter
#ToString
public class IncidenceDo implements BaseDo {
private static final long serialVersionUID = 1L;
#Id
#Column(name="INCIDENCE_ID")
private String incidenceId;
#Column(name="PRIORITY")
private String priority;
#Column(name="TITLE")
private String title;
#Column(name="BODY")
private String body;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "CREATED_AT")
private Date createdAt;
#Column(name="CREATED_BY")
private String createdBy;
#Column(name="TRIP_ID")
private String tripId;
#Column(name="SHIPMENT_ID")
private Long shipmentId;
#Column(name="RECIPIENT")
private String recipient;
#Column(name="LATITUDE")
private Double latitude;
#Column(name="LOGITUDE")
private Double logitude;
#Column(name="ADDRESS")
private String address;
#Column(name="DELETED")
private Integer deleted=0;
#OneToMany(targetEntity = CommentsDo.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(name="INCIDENCE_COMMENTS",joinColumns={ #JoinColumn(name="INCIDENCE_ID") },inverseJoinColumns = {
#JoinColumn(name = "COMMENT_ID") })
private List<CommentsDo> comments=new ArrayList<CommentsDo>();
#ManyToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
#JoinTable(name = "INCIDENCE_USERS", joinColumns = { #JoinColumn(name = "INCIDENCE_ID") }, inverseJoinColumns = {
#JoinColumn(name = "USER_ID") })
private Set<UserDetailsDo> users=new HashSet<UserDetailsDo>(0);
public void setDeleted() {
this.deleted=1;
}
#Override
public Object getPrimaryKey() {
// TODO Auto-generated method stub
return incidenceId;
}
}
My CommentDO is
package com.incture.metrodata.entity;
import java.util.Date;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
enter code here
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
#Entity
#Table(name="COMMENTS")
#Getter
#Setter
#ToString
public class CommentsDo implements BaseDo{
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#Column(name = "COMMENT_ID")
#GeneratedValue(strategy = GenerationType.AUTO)
private long commentId;
#Lob
private String comment;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "CREATED_AT")
private Date createdAt;
#Column(name = "CREATED_BY")
private String createdBy;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "UPDATED_AT")
private Date updatedAt;
#Column(name = "IS_DELETED")
private int isDeleted=0;
#Override
public Object getPrimaryKey() {
return commentId;
}
}
Method to save the comment
// Create
public D create(D dto,E dos) throws Exception {
// persisting the dto
E e = importDto(dto,dos);
persist(e);
getSession().flush();
getSession().clear();
return exportDto(e);
}
impordto() method is
IncidenceDo importDto(IncidenceDTO dto, IncidenceDo dos) throws Exception {
if (ServicesUtil.isEmpty(dos))
dos = new IncidenceDo();
if (!ServicesUtil.isEmpty(dto)) {
if (!ServicesUtil.isEmpty(dto.getIncidenceId()))
dos.setIncidenceId(dto.getIncidenceId());
if (!ServicesUtil.isEmpty(dto.getPriority()))
dos.setPriority(dto.getPriority());
if (!ServicesUtil.isEmpty(dto.getBody()))
dos.setBody(dto.getBody());
if (!ServicesUtil.isEmpty(dto.getTitle()))
dos.setTitle(dto.getTitle());
if (!ServicesUtil.isEmpty(dto.getCreatedAt()))
dos.setCreatedAt(dto.getCreatedAt());
if (!ServicesUtil.isEmpty(dto.getTripId()))
dos.setTripId(dto.getTripId());
if (!ServicesUtil.isEmpty(dto.getShipmentId()))
dos.setShipmentId(dto.getShipmentId());
if (!ServicesUtil.isEmpty(dto.getRecipient()))
dos.setRecipient(dto.getRecipient());
if (!ServicesUtil.isEmpty(dto.getLatitude()))
dos.setLatitude(dto.getLatitude());
if (!ServicesUtil.isEmpty(dto.getLogitude()))
dos.setLogitude(dto.getLogitude());
if (!ServicesUtil.isEmpty(dto.getDeleted()))
dos.setDeleted(dto.getDeleted());
if (!ServicesUtil.isEmpty(dto.getCreatedBy()) && dto.getCreatedBy() instanceof String) {
dos.setCreatedBy(dto.getCreatedBy().toString());
}
// parsing comments
if (!ServicesUtil.isEmpty(dto.getComments())) {
List<CommentsDo> comments = commentDao.importList(dto.getComments(), dos.getComments());
dos.setComments(comments);
}
importList
public List<E> importList(List<D> dList,List<E> eList) throws Exception {
List<E> list = new ArrayList<E>();
for (D d : dList) {
E dos = null;
try {
dos = getByKeysForFK(d);
for(E e : eList){
if( d.getPrimaryKey().equals(e.getPrimaryKey())){
dos = e;
break;
}
}
} catch (Exception e) {
}
list.add(importDto(d,dos));
}
return list;
}
I'm having problems in mapping foreign keys as the primary key.
My tables are:
client:
PK: id_client
games:
PK: id_game
tickets:
PK: (id_game_fk references game(id_game), id_client_fk references client(id_client))
And here are the classes I have defined as entities:
Client.java:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "client")
public class Client {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id_client")
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
Games.java:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "games")
public class Games {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id_game")
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
Ticket.java:
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import Client;
import Games;
#Entity
#Table(name = "tickets")
public class Ticket implements Serializable {
private static final long serialVersionUID = 3287868602749718327L;
#EmbeddedId
private TicketId ticketId;
#ManyToOne
#JoinColumn(name = "id_game")
private Games games;
#ManyToOne
#JoinColumn(name = "id_client")
private Client client;
public TicketId getId() {
return ticketId;
}
public void setId(TicketId id) {
this.ticketId = id;
}
public Games getGames() {
return games;
}
public void setGames(Games games) {
this.games = games;
}
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
}
TicketId.java:
import java.io.Serializable;
import javax.persistence.Embeddable;
#Embeddable
public class TicketId implements Serializable {
private static final long serialVersionUID = 6220676431741410239L;
private int idGameFk;
private int idClientFk;
public TicketId(int idGameFk, int idClientFk) {
this.idGameFk = idGameFk;
this.idClientFk = idClientFk;
}
public int getIdGameFk() {
return idGameFk;
}
public void setIdGameFk(int idGameFk) {
this.idGameFk = idGameFk;
}
public int getIdClientFk() {
return idClientFk;
}
public void setIdClientFk(int idClientFk) {
this.idClientFk = idClientFk;
}
}
I have tried all the advices I have found so far, but none of them helped. Also, I need this PK to be composed by foreign keys, so I really need help to solve out, how should I map it correctly.
You can use #MapsId :
#Entity
#Table(name = "tickets")
public class Ticket implements Serializable {
private static final long serialVersionUID = 3287868602749718327L;
#EmbeddedId
private TicketId ticketId;
#ManyToOne
#MapsId("idGameFk")
#JoinColumn(name = "id_game_fk")
private Games games;
#ManyToOne
#MapsId("idClientFk")
#JoinColumn(name = "id_client_fk")
private Client client;
....
}
More info here : http://docs.oracle.com/javaee/6/api/javax/persistence/MapsId.html