I'm working on an application with following Entities and code:
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Clip {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private long size;
private long date;
public Clip() {
}
public long getId() {
return id;
}
public long getSize() {
return size;
}
public long getDate() {
return date;
}
}`
#Entity
public class MotionPicture extends Clip {
private long duration;
#OneToMany(fetch = FetchType.LAZY)
List<Clip> clips = new ArrayList<Clip>();
public MotionPicture() {
}
public MotionPicture(long duration) {
this.duration = duration;
}
public List<Clip> getClips() {
return clips;
}
public long getDuration() {
return duration;
}
}
The RestController for MotionPicture:
#CrossOrigin
public class MotionPictureRestController {
#Autowired
private MotionPictureRepository motionPictureRepository;
#GetMapping(value = "universal2/motionpicture")
public ResponseEntity<List<MotionPicture>> getMotionPicture() {
List<MotionPicture> result = this.motionPictureRepository.findAll();
if (!result.isEmpty()) {
return new ResponseEntity<List<MotionPicture>>(result, HttpStatus.OK);
} else {
return new ResponseEntity<List<MotionPicture>>(HttpStatus.NOT_FOUND);
}
}
#GetMapping(value = "universal2/motionpicture/{id}")
public ResponseEntity<MotionPicture> getMotionPictureById(#PathVariable("id") long id) {
Optional<MotionPicture> result = this.motionPictureRepository.findById(id);
if (result.isPresent()) {
return new ResponseEntity<MotionPicture>(result.get(), HttpStatus.OK);
} else {
return new ResponseEntity<MotionPicture>(HttpStatus.NOT_FOUND);
}
}
}
My DB
Table: clip
columns: id(1-100 unique), date, size
Table: motion_picture
columns: id(1-100 unique), date, size, duration
association table: motion_picture_clips
columns: motion_picture_id (1-100 random), clips_id (1-100 unique)
When I run the programm and make a the getRequest in Postman (getById and getAll) --> I'll get duplicated values back
JSON from Postman: (localhost/DB/motionpicture/2)
{
"id": 2,
"size": 7040,
"date": 2006,
"duration": 2899,
"clips": [
{
"id": 73,
"size": 7246,
"date": 2009
},
{
"id": 73,
"size": 7246,
"date": 2009
}
]
}
How can I change the code or the DB to get only one clip with id 73 back?
I would be very grateful for your help:)
Kind regards!
Try to use
#OneToMany(fetch = FetchType.LAZY)
Set<Clip> clips = new HashSet<Clip>();
instead of :
#OneToMany(fetch = FetchType.LAZY)
List<Clip> clips = new ArrayList<Clip>();
Related
I am making a REST api in Java with Spring boot JPA Hibernate and with H2 database, I am trying to do a POST to "api/facturas" which is the RequestMapping of FacturaController, in which I want to add data to the FacturaDetalles List, but It returns an empty array, as if the data had never been sent, what am I doing wrong here?
I am trying to make a POST to "/api/facturas" like this:
{
"cliente": {
"idCliente": 1
},
"facturaDetalles": [
{
"producto": {
"idProducto": 3
}
}
]
}
This is what it should return:
{
"cliente": {
"idCliente": 1,
"nombreCliente": "Juan",
"apellidoCliente": "Rufiol",
"dni": 35884121,
"direccionCliente": "Av. Siempre Viva 300",
"telefonoCliente": 353654128,
"emailCliente": "juancito#gmail.com",
"cuit": 5412456985510,
"ciudad": "Capital Federal",
"provincia": "Buenos Aires",
"pais": "Argentina",
"codigoPostal": 1426,
"fechaNacimiento": "10-10-1980"
},
"facturaDetalles": [
{
"idFacturaDetalles": 1,
"producto": {
"idProducto": 3,
"nombreProducto": "Pollo frito",
"precioProducto": 40,
"descripcion": "Una delicia king chicken",
"stock": 3
}
}
]
}
This is what i get:
{
"cliente": {
"idCliente": 1,
"nombreCliente": "Juan",
"apellidoCliente": "Rufiol",
"dni": 35884121,
"direccionCliente": "Av. Siempre Viva 300",
"telefonoCliente": 353654128,
"emailCliente": "juancito#gmail.com",
"cuit": 5412456985510,
"ciudad": "Capital Federal",
"provincia": "Buenos Aires",
"pais": "Argentina",
"codigoPostal": 1426,
"fechaNacimiento": "10-10-1980"
},
"facturaDetalles": []
}
[data.sql]
INSERT INTO clientes (nombre,apellido,dni,direccion,telefono,email,cuit,ciudad,provincia,pais,codigo_postal, fecha_nacimiento ) VALUES ('Juan','Rufiol','35884121','Av. Siempre Viva 300','353654128','juancito#gmail.com','5412456985510','Capital Federal','Buenos Aires', 'Argentina',1426,'10-10-1980' );
INSERT INTO clientes (nombre,apellido,dni,direccion,telefono,email,cuit,ciudad,provincia,pais,codigo_postal, fecha_nacimiento ) VALUES ('Rolo','Garcia','41882121','Mariano Moreno 44','353614128','rolaso#rol.com','51134569854113','Capital Federal','Buenos Aires', 'Argentina',1426,'01-03-1989' );
INSERT INTO facturas (nro_factura,tipo_factura,precio_total_factura,id_cliente) VALUES (4444,'A',2000,1);
INSERT INTO facturas (nro_factura,tipo_factura,precio_total_factura,id_cliente ) VALUES (4444,'A',2000,1);
INSERT INTO facturas_detalles (cantidad,subtotal,id_facturas ,id_producto) VALUES (1,1,1,3);
INSERT INTO facturas_detalles (cantidad,subtotal,id_facturas ,id_producto) VALUES (1,1,1,2);
[Factura]
#Entity
#Table(name = "facturas")
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Factura {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long idFactura;
#Column(name = "nro_factura")
private Integer nroFactura;
#Column(name = "tipo_factura")
private String tipoFactura;
#Column(name = "fecha", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private String fechaFactura;
#Column(name = "precio_total_factura")
private Integer precioTotalFactura;
#OneToOne
#JoinColumn(name = "id_cliente")
private Cliente cliente;
#JsonManagedReference
#OneToMany(mappedBy = "factura", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<FacturaDetalles> facturaDetalles = new ArrayList<>();
#OneToOne
#JoinColumn(name = "id_empresa")
private Empresa empresa;
}
[FacturaDTO]
#Data
#AllArgsConstructor
#NoArgsConstructor
public class FacturaDTO {
private ClienteDTO cliente;
private List<FacturaDetallesDTO> facturaDetalles;
}
[FacturaServiceImp]
#Service
public class FacturaServiceImp implements FacturaService {
#Autowired
private FacturaRepository facturaRepository;
public List<Factura> getAllFacturas() {
return facturaRepository.findAll();
}
public Factura getOneFactura(Long id) {
return facturaRepository.findById(id).orElseThrow(() -> new RuntimeException("Factura no encontrado"));
}
public Factura createFactura(Factura factura) {
return facturaRepository.save(factura);
}
public void deleteFactura(Long id) {
facturaRepository.deleteById(id);
}
}
[FacturaService]
public interface FacturaService {
List<Factura> getAllFacturas();
Factura getOneFactura(Long id);
Factura createFactura(Factura factura);
void deleteFactura(Long id);
}
[FacturaController]
#RestController
#RequestMapping("/api/facturas")
public class FacturaController {
#Autowired
ModelMapper modelMapper;
#Autowired
FacturaService facturaService;
#GetMapping()
public List<FacturaDTO> getAllFacturas() {
return facturaService.getAllFacturas().stream().map(factura -> modelMapper.map(factura, FacturaDTO.class)).collect(Collectors.toList());
}
#GetMapping("/{id}")
public ResponseEntity<FacturaDTO> getOneFactura(#PathVariable Long id) {
Factura factura = facturaService.getOneFactura(id);
FacturaDTO facturaDTO = modelMapper.map(factura, FacturaDTO.class);
return ResponseEntity.ok().body(facturaDTO);
}
#PostMapping()
public ResponseEntity<FacturaDTO> createFactura(#RequestBody FacturaDTO facturaDTO) {
Factura factura = modelMapper.map(facturaDTO, Factura.class);
Factura facturaCreacion = facturaService.createFactura(factura);
FacturaDTO conversion = modelMapper.map(facturaCreacion, FacturaDTO.class);
return new ResponseEntity<FacturaDTO>(conversion, HttpStatus.CREATED);
}
#DeleteMapping("/{id}")
public ResponseEntity<FacturaDTO> deleteFactura(#PathVariable Long id) {
Factura factura = facturaService.getOneFactura(id);
facturaService.deleteFactura(id);
FacturaDTO facturaDTO = modelMapper.map(factura, FacturaDTO.class);
return ResponseEntity.ok().body(facturaDTO);
}
}
[FacturaDetalles]
#Entity(name = "facturas_detalles")
#Table(name = "facturas_detalles")
#Data
#AllArgsConstructor
#NoArgsConstructor
public class FacturaDetalles {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long idFacturaDetalles;
#Column(name = "cantidad")
private Integer cantidadProductos;
#Column(name = "subtotal")
private Integer totalParcial;
#JsonBackReference
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "id_facturas")
private Factura factura;
#OneToOne
#JoinColumn(name = "id_producto")
private Producto producto;
}
[FacturaDetallesDTO]
#Data
#AllArgsConstructor
#NoArgsConstructor
public class FacturaDetallesDTO {
private Long idFacturaDetalles;
private ProductoDTO producto;
}
[FacturaDetallesServiceImp]
#Service
public class FacturaDetallesServiceImp implements FacturaDetallesService {
#Autowired
private FacturaDetallesRepository facturaDetallesRepository;
public List<FacturaDetalles> getAllFacturaDetalles() {
return facturaDetallesRepository.findAll();
}
public FacturaDetalles getOneFacturaDetalles(Long id) {
return facturaDetallesRepository.findById(id).orElseThrow(() -> new RuntimeException("Factura no encontrado"));
}
public FacturaDetalles createFacturaDetalles(FacturaDetalles facturaDetalles) {
return facturaDetallesRepository.save(facturaDetalles);
}
public void deleteFacturaDetalles(Long id) {
facturaDetallesRepository.deleteById(id);
}
}
[FacturaDetallesService]
public interface FacturaDetallesService {
List<FacturaDetalles> getAllFacturaDetalles();
FacturaDetalles getOneFacturaDetalles(Long id);
void deleteFacturaDetalles(Long id);
FacturaDetalles createFacturaDetalles(FacturaDetalles facturaDetalles);
}
[FacturaDetallesController]
#RestController
#RequestMapping("/api/detalles")
public class FacturaDetallesController {
#Autowired
ModelMapper modelMapper;
#Autowired
FacturaDetallesService facturaDetallesService;
#GetMapping()
public List<FacturaDetallesDTO> getAllFacturaDetalles() {
return facturaDetallesService.getAllFacturaDetalles().stream().map(facturaDetalles -> modelMapper.map(facturaDetalles, FacturaDetallesDTO.class)).collect(Collectors.toList());
}
#GetMapping("/{id}")
public ResponseEntity<FacturaDetallesDTO> getOneFacturaDetalles(#PathVariable Long id) {
FacturaDetalles facturaDetalles = facturaDetallesService.getOneFacturaDetalles(id);
FacturaDetallesDTO detallesDTO = modelMapper.map(facturaDetalles, FacturaDetallesDTO.class);
return ResponseEntity.ok().body(detallesDTO);
}
#PostMapping()
public ResponseEntity<FacturaDetallesDTO> createFacturaDetalles(#RequestBody FacturaDetallesDTO facturaDetallesDTO) {
FacturaDetalles facturaDetalles = modelMapper.map(facturaDetallesDTO, FacturaDetalles.class);
FacturaDetalles facturaDetallesCreacion = facturaDetallesService.createFacturaDetalles(facturaDetalles);
FacturaDetallesDTO conversion = modelMapper.map(facturaDetallesCreacion, FacturaDetallesDTO.class);
return new ResponseEntity<FacturaDetallesDTO>(conversion, HttpStatus.CREATED);
}
#DeleteMapping("/{id}")
public ResponseEntity<FacturaDetallesDTO> deleteFacturaDetalles(#PathVariable Long id){
FacturaDetalles facturaDetalles = facturaDetallesService.getOneFacturaDetalles(id);
facturaDetallesService.deleteFacturaDetalles(id);
FacturaDetallesDTO detallesDTO = modelMapper.map(facturaDetalles, FacturaDetallesDTO.class);
return ResponseEntity.ok().body(detallesDTO);
}
}
try like this (lines omitted due to readability, e.g. checks)
#Autowired
private FacturaRepository facturaRepository;
#Autowired
private FacturaDetallesRepository facturaDetallesRepository;
public Factura createFactura(...) {
// get factura from db (by id from dto)
Factura factura = facturaRepository.findByIdFactura(facura.getIdFactura())
// get facturaDetalles from db (by id from dto)
FacturaDetalles facturaDetalles = facturaDetallesRepository.findByIdFacturaDetalles(...)
// link entites, for each detalles object!
facturaDetalles.setFactura(factura)
// add to list, but check if already in list first
factura.getFacturaDetalles().add(facturaDetalles)
facturaRepository.save(factura);
}
I have several entities
post
public class Post {
#Id
#SequenceGenerator(name = "jpaSequence.Post",
sequenceName = "SEQUENCE_POST",
allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "jpaSequence.Post")
private Long id;
private String subject;
#OneToMany(mappedBy = "post", fetch = FetchType.LAZY)
private List<Comment> comments = new ArrayList<>();
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn
private User user;
comment
#Entity
#Table(name = "comments")
public class Comment {
#Id
#SequenceGenerator(name = "jpaSequence.Comment",
sequenceName = "SEQUENCE_COMMENT",
allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "jpaSequence.Comment")
private Long id;
private String reply;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn
private Post post;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn
private User user;
user
#Entity
#Table(name = "users")
public class User {
#Id
#SequenceGenerator(name = "jpaSequence.User",
sequenceName = "SEQUENCE_USER",
allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "jpaSequence.User")
private Long id;
private String name;
private String email;
postDto
public class PostDto {
private Long id;
private String subject;
private List<CommentDto> comments = new ArrayList<>();
private UserDto user;
commentDto
public class CommentDto {
private Long id;
private String reply;
private PostDto post;
private UserDto user;
userDto
public class UserDto {
private Long id;
private String name;
private String email;
mapper
#Mapper(componentModel = "spring")
public interface PostMapper {
Post postDtoToPostEntity(PostDto dto);
#Mapping(target = "post.comments", ignore = true)
CommentDto toCommentDto(Comment entity);
#Mapping(target = "comments", source = "entity.comments", qualifiedBy = CommentListDtoAnnotation.class)
PostDto postEntityToPostDto(Post entity);
#CommentListDtoAnnotation
default Iterable<CommentDto> commentListEntityToCommentListDto(Iterable<Comment> source) {
Iterable<CommentDto> collect = StreamSupport.stream(source.spliterator(), false)
.map(this::toCommentDto)
.peek(dto -> dto.setPost(null))
.collect(Collectors.toList());
return collect;
}
Iterable<Post> postListDtoToPostListEntity(Iterable<PostDto> list);
Iterable<PostDto> postListEntityToPostListDto(Iterable<Post> list);
}
commentMapper
#Mapper(componentModel = "spring")
public interface CommentMapper {
Comment commentDtoToCommentEntity (CommentDto dto);
#Mapping(target = "post.comments", ignore = true)
CommentDto commentEntityToCommentDto(Comment entity);
Iterable<Comment> commentListDtoToCommentListEntity(Iterable<CommentDto> list);
Iterable<CommentDto> commentListEntityToCommentListDto(Iterable<Comment> list);
}
annotation
import org.mapstruct.Qualifier;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Qualifier
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.CLASS)
public #interface CommentListDtoAnnotation {
}
But when the mapping takes place I get the following response:
{
"id": 1,
"subject": "JPA Entity Graph In Action",
"comments": [
{
"id": 1,
"reply": "Nice !!",
"post": {
"id": 1,
"subject": "JPA Entity Graph In Action",
"comments": [],
"user": {
"id": 1,
"name": "user1",
"email": "user1#test.com"
}
},
"user": {
"id": 2,
"name": "user2",
"email": "user2#test.com"
}
},
{
"id": 2,
"reply": "Cool !!",
"post": {
"id": 1,
"subject": "JPA Entity Graph In Action",
"comments": [],
"user": {
"id": 1,
"name": "user1",
"email": "user1#test.com"
}
},
"user": {
"id": 3,
"name": "user3",
"email": "user3#test.com"
}
}
],
"user": {
"id": 1,
"name": "user1",
"email": "user1#test.com"
}
}
Update_1
service
#Service
public class PostReadServiceImpl implements PostReadService {
private PostRepository repository;
private PostWithoutNestedLevelsTransformers transformer;
#Autowired
public PostReadServiceImpl(PostRepository repository,
PostWithoutNestedLevelsTransformers transformer) {
this.repository = repository;
this.transformer = transformer;
}
#Override
public PostDto getEntryById(Long id) {
Post entity = findEntry(id);
PostDto postDto = this.transformer.transformEntityToDto(entity);
return postDto;
}
private Post findEntry(Long id) {
return this.repository.findById(id).orElseThrow(() -> new RuntimeException("Post not found!"));
}
#Transactional
#Override
public Iterable<PostDto> getListPosts() {
Iterable<Post> posts = findListPosts();
Iterable<PostDto> postDtoList = this.transformer.transformListEntityToDtoList(posts);
return postDtoList;
}
private Iterable<Post> findListPosts() {
Iterable<Post> posts = this.repository.findAll();
return posts;
}
private Iterable<Comment> pickUpComment (List<Comment> comments ) {
List<Comment> listComment = new ArrayList<>();
for (Comment comment : comments) {
Comment conversionComment = moveData(comment);
listComment.add(conversionComment);
}
return listComment;
}
private Comment moveData(Comment comment) {
Comment conversionComment = new Comment();
String commentReply = comment.getReply();
Long idUser = comment.getId();
conversionComment.setId(idUser);
conversionComment.setReply(commentReply);
return conversionComment;
}
}
transformer
#Component
public class PostTransformer {
private PostMapper mapper;
#Autowired
public PostTransformer(PostMapper mapper) {
this.mapper = mapper;
}
public PostDto transformEntityToDto(Post entity) {
PostDto postDto = this.mapper.postEntityToPostDto(entity);
return postDto;
}
public Post transformDtoToEntity(PostDto dto) {
return this.mapper.postDtoToPostEntity(dto);
}
public Iterable<PostDto> transformListEntityToDtoList(Iterable<Post> listEntity) {
Iterable<PostDto> postDtoList = this.mapper.postListEntityToPostListDto(listEntity);
return postDtoList;
}
public Iterable<Post> transformListDtoToEntityList(Iterable<PostDto> listDto) {
return this.mapper.postListDtoToPostListEntity(listDto);
}
}
The method must be executed:
#CommentListDtoAnnotation
default Iterable<CommentDto> commentListEntityToCommentListDto(Iterable<Comment> source) {
But it is not.
In the field comment, nested field - post - must be null...
I don't understand what I'm doing wrong.
I want to search in spring data jpa by bedType. But, bedType is not string. Not String bedType but BedType bedType(Object). Here is my repository
#Query("select a,b.bedType,b.roomCategory from RoomDetail a left outer join RoomMaster b on a.roomId = b.id where lower(b.bedType) like %:bedType%")
<Page>RoomDetail findByBedType(
#Param("bedType") BedType bedType,
Pageable paging);
FindRoomStatus.Java
public class FindRoomStatus {
private BedType bedType;
public BedType getBedType() {
return bedType;
}
public void setBedType(BedType bedType) {
this.bedType = bedType;
}
In my controller, I have got error
String cannot be a converted to BedType
data = roomDetailRepository.findByBedType(findRoomStatus.getBedType().toString(), paging);
Here is BedType.Java
public class BedType implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY, generator = "bed_type_seq")
#SequenceGenerator(name = "bed_type_seq", sequenceName = "bed_type_id_bed_type_seq", allocationSize = 1, initialValue = 1)
private int id;
#Column(name = "bed_type_name", length = 20)
private String bedTypeName;
#JsonIgnore
#Column(name = "status", length = 10)
private String status;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBedTypeName() {
return bedTypeName;
}
public void setBedTypeName(String bedTypeName) {
this.bedTypeName = bedTypeName;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
List Room Status, in this list, i want to find by BedType
{
"id": 105,
"roomId": 43,
"floor": "1",
"roomNumber": "001",
"description": "Normal",
"status": "Vacant Clean"
},
{
"id": 11,
"bedTypeName": "King size"
},
{
"id": 39,
"categoryName": "President Suite"
}
You are using LIKE keyword in the query but you are accepting BedType object as a parameter in your query. You are sending String as an argument from your controller. This is the problem. toString method will give the string representation of an object.
What you can do is, change the parameter to String which accepts bedTypeName like:
#Query("select a,b.bedType,b.roomCategory from RoomDetail a left outer
join RoomMaster b on a.roomId = b.id where lower(b.bedType.bedTypeName) like
%:bedTypeName%")
<Page>RoomDetail findByBedType(
#Param("bedTypeName") String bedTypeName,
Pageable paging);
And from the controller,
data = roomDetailRepository.findByBedType(findRoomStatus.getBedType().getBedTypeName(),
paging);
I'm trying to get schedules data from mongoDb.
I created the appropriate aggregation and tried to convert it within Spring Framework.
db.theaters.aggregate([
{ $match: { 'city_id': <someCityId>, 'theatreRooms.schedules.spectacle_id': <someSpecId> } },
{ $unwind: '$theatreRooms' },
{ $unwind: '$theatreRooms.schedules' },
{ $group: { _id: { name: '$name', room: '$theatreRooms.name' }, schedules: { $addToSet: '$theatreRooms.schedules.time' } } },
{ $group: { _id: '$_id.name', schedules: { $addToSet: { room: '$_id.room', schedules: '$schedules' } } } }
])
I've created properly match and unwind operations. But I've got problem with first group operation.
It seems that the operation is well interpreted, but for some reason I am not able to properly map the _id object.
Here is my code example:
public class TheaterProject {
private TheaterId _id;
private List<String> schedules;
public TheaterId get_id() {
return _id;
}
public void set_id(TheaterId _id) {
this._id = _id;
}
public List<String> getSchedules() {
return schedules;
}
public void setSchedules(List<String> schedules) {
this.schedules = schedules;
}
}
public class TheaterId {
#Field("name")
private String name;
#Field("room")
private Integer room;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getRoom() {
return room;
}
public void setRoom(Integer room) {
this.room = room;
}
}
public Document getRawSchedules(String cityId, String spectaclesId){
MatchOperation match = Aggregation.match(Criteria.where("city_id").is(cityId).and("theatreRooms.schedules.spectacle_id").is(spectaclesId));
UnwindOperation theaterUnwind = Aggregation.unwind("theatreRooms");
UnwindOperation schedulesUnwind = Aggregation.unwind("theatreRooms.schedules");
GroupOperation firstGroup = Aggregation.group(Fields.from(
Fields.field("name", "name"),
Fields.field("room", "theatreRooms.name")))
.addToSet("theatreRooms.schedules.time").as("schedules");
Aggregation agg = Aggregation.newAggregation(match,theaterUnwind,schedulesUnwind,firstGroup);
Document theaters = mongoTemplate.aggregate(agg, Theater.class, TheaterProject.class).getRawResults();
return theaters;
}
public List<TheaterProject> getSchedules(String cityId, String spectaclesId){
MatchOperation match = Aggregation.match(Criteria.where("city_id").is(cityId).and("theatreRooms.schedules.spectacle_id").is(spectaclesId));
UnwindOperation theaterUnwind = Aggregation.unwind("theatreRooms");
UnwindOperation schedulesUnwind = Aggregation.unwind("theatreRooms.schedules");
GroupOperation firstGroup = Aggregation.group(Fields.from(
Fields.field("name", "name"),
Fields.field("room", "theatreRooms.name")))
.addToSet("theatreRooms.schedules.time").as("schedules");
Aggregation agg = Aggregation.newAggregation(match,theaterUnwind,schedulesUnwind,firstGroup);
List<TheaterProject> theaters = mongoTemplate.aggregate(agg, Theater.class, TheaterProject.class).getMappedResults();
return theaters;
}
When I've invoked method getSchedules which return mapped objects, _id field is equal to null.
[
{
"_id": null,
"schedules": [
"5:15"
]
},
{
"_id": null,
"schedules": [
"6:55",
"4:35",
"10:15"
]
}
]
But when I've invoked getRawSchedules which used getRawResults it's looking properly.
{
"results": [
{
"_id": {
"name": "Pinokio",
"room": 2
},
"schedules": [
"5:15"
]
},
{
"_id": {
"name": "Roma",
"room": 1
},
"schedules": [
"6:55",
"4:35",
"10:15"
]
}
]
}
I don't have any idea why it's working like that.
I didn't find any information about this problem in the documentation and here. But I have a solution. You may just rename the field from _id to something else. theaterId for example. I don't know all requirements for your issue but you may do it just on mapping level.
Fix the mapping
import org.springframework.data.mongodb.core.mapping.Field;
import java.util.List;
public class TheaterProject {
#Field("theaterId")
private TheaterId _id;
private List<String> schedules;
public TheaterId get_id() {
return _id;
}
public void set_id(TheaterId _id) {
this._id = _id;
}
public List<String> getSchedules() {
return schedules;
}
public void setSchedules(List<String> schedules) {
this.schedules = schedules;
}
}
But it requires additional projection step
public List<TheaterProject> getSchedules(String cityId, String spectaclesId){
...
GroupOperation firstGroup = Aggregation.group(Fields.from(
Fields.field("name", "name"),
Fields.field("room", "theatreRooms.name")))
.addToSet("theatreRooms.schedules.time").as("schedules");
ProjectionOperation projection = Aggregation.project(Fields.from(
Fields.field("theaterId", "_id"),
Fields.field("schedules", "schedules")));
Aggregation agg = Aggregation.newAggregation( ... ,firstGroup, projection);
List<TheaterProject> theaters = mongoTemplate.aggregate(agg, "collectionName", TheaterProject.class).getMappedResults();
return theaters;
}
I am working with a project .I use springboot and Jpa.It works perfectly and insert data into DB when Program runs.But when i want to save data via postman then it shows BadRequest.How can i create my controller for this kind of classes. like:
CrickerPlayer:
public class CricketPlayer extends PlayerProfile {
#Id
private String playerId;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "cricketPlayer")
private List<Performance> performanceList;
#ManyToMany(fetch = FetchType.EAGER)
#JoinColumn(name = "play_for_Team")
private List<PlayForTeam> playForTeamList;
//getters and setters
}
PlayerProfile:
public class PlayerProfile {
private String image;
private String name;
private int age;
private LocalDate dob;
private double height;
private String nationality;
private int jerseyNo;
private String game;
}
Performance.class
public class Performance {
#Id
private String performanceId;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "id")
private Game match;
private long[] runsScored;
private int fours;
private int sixes;
private int ballsFaced;
private String[] oversBowled;
private int bowled;
private int wickets;
private double BattingAverage;
private double BowlingAverage;
private double economy;
private int totalStumping;
private double strikeRate;
private int highestScore;
private int totalMaidens;
private int totalCatches;
#OneToMany(cascade = CascadeType.ALL)
private List<Role> performanceRoleList;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "player_id")
private CricketPlayer cricketPlayer;
}
There's some entity also Ground,series game and a Gametype enum. like:
Game.class
public class Game {
#Id
private String id;
#Enumerated
private MatchType matchType;
#OneToOne(cascade = CascadeType.ALL)
private Ground ground;
#OneToOne(cascade = CascadeType.ALL)
private Series series;
#OneToMany(cascade = CascadeType.ALL)
private List<CricketPlayer> cricketPlayers;
}
Ground.class
public class Ground {
#Id
private String groundId;
private String groundName;
}
MatchType.enum
public enum MatchType {
ODI,
TEST,
T20,
T10;
}
RestController.class
#Controller
#RequestMapping(value = "api/cricketplayer")
#AllArgsConstructor
public class CricketPlayerRest {
#Autowired
private final CricketPlayerService cricketPlayerService;
private Game game1;
private Ground ground1;
private Series series1;
private Performance performance1;
private Role role1;
private PlayForTeam playForTeam1;
private CricketPlayer cricketPlayer1;
private WrapperClass wrapperClass;
List<Performance> performanceList = new ArrayList<>();
List<PlayForTeam> playForTeamList = new ArrayList<>();
List<Role> roleList = new ArrayList<>();
List<CricketPlayer> playForTeamCricketer = new ArrayList<>();
List<CricketPlayer> gameListForCricketer = new ArrayList<>();
#GetMapping(value = "all")
#ResponseBody
public ResponseEntity<?> getAllPlayers() {
return ResponseEntity.status(HttpStatus.OK).body(cricketPlayerService.findAllPlayers());
}
#GetMapping(value = "name")
#ResponseBody
public ResponseEntity<?> getPlayerByName(#RequestParam String name) {
Optional<CricketPlayer> cricketPlayer = cricketPlayerService.getPlayerByName(name);
if (cricketPlayer.isPresent()) {
return ResponseEntity.status(HttpStatus.OK).body(cricketPlayer.get());
} else {
return ResponseEntity.badRequest().body(null);
}
}
#GetMapping(value = "{id}")
public ResponseEntity<?> getPlayerById(#PathVariable String id) {
Optional<CricketPlayer> cricketPlayer = cricketPlayerService.findPlayersById(id);
if (cricketPlayer.isPresent()) {
return ResponseEntity.status(HttpStatus.OK).body(cricketPlayer.get());
} else {
return ResponseEntity.badRequest().body(null);
}
}
#PostMapping(value = "save",
produces = MediaType.APPLICATION_JSON_VALUE,
consumes = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ResponseEntity<?> createPlayer(#RequestBody CricketPlayer cricketPlayer) {
try {
CricketPlayer createdPlayer = cricketPlayerService.save(cricketPlayer);
ResponseEntity<CricketPlayer> cricketPlayerResponseEnity = ResponseEntity
.status(HttpStatus.CREATED)
.body(createdPlayer);
return cricketPlayerResponseEnity;
} catch (Exception e) {
return ResponseEntity.badRequest().body(null);
}
}
}
There also repository for every entity.
Can anyone help me out for this project that how can i update a cricketPlayer with setting every entity.
My project link is: You see it here also in github
Postman data:
{
"image": "Musta",
"name": "Musta",
"age": 28,
"dob": "1985-04-02",
"height": 167,
"nationality": "Bangladeshi",
"jerseyNo": 28,
"game": "Cricket",
"playerId": "Musta",
"performanceList": [
{
"performanceId": "BD-NZ",
"match": {
"id": "1",
"matchType": "ODI",
"ground": {
"groundId": "Mirpur",
"groundName": "SHERE Bangla"
},
"series": {
"seriesId": "Walton",
"seriesName": "walton Series"
}
},
"runsScored": [
2,
0,
1,
3,
4,
6
],
"fours": 4,
"sixes": 2,
"ballsFaced": 12,
"oversBowled": [
"w",
"2",
"6",
"1",
"4",
"0"
],
"bowled": 0,
"wickets": 1,
"economy": 5.4,
"totalStumping": 1,
"strikeRate": 154.4,
"highestScore": 154,
"totalMaidens": 0,
"totalCatches": 5,
"performanceRoleList": [
{
"roleId": 3,
"type": "All-Rounder"
}
],
"bowlingAverage": 31.6,
"battingAverage": 25
}
],
"playForTeamList": [
{
"pftId": "sun",
"team": {
"id": "sun",
"teamName": "sun"
},
"startsDate": "2011-03-01",
"endsDate": "2013-03-31"
}
]
}