Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5a2598a
Remove internal dto, update mapper
PIPetkova19 Jul 7, 2026
81bd802
Update roomService by implementing baseService
PIPetkova19 Jul 7, 2026
8527924
Add room facade layer
PIPetkova19 Jul 7, 2026
5217de6
Update controller to use facade layer
PIPetkova19 Jul 7, 2026
cd5b74c
Add tests for room service
PIPetkova19 Jul 8, 2026
93be8fa
Add tests for roomMapper
PIPetkova19 Jul 8, 2026
5745b77
Add tests for RoomWebFacade
PIPetkova19 Jul 8, 2026
f8fc9aa
Include category in room response
PIPetkova19 Jul 15, 2026
18a22b8
Change to left join instead of inner
PIPetkova19 Jul 20, 2026
2109a9e
Use Criteria API instead of jpql in room repository
PIPetkova19 Jul 20, 2026
01bbc6c
Update mapper test
PIPetkova19 Jul 20, 2026
c1969bc
Update room web facade tests
PIPetkova19 Jul 20, 2026
68610f8
Change findRoomResponseById signature
PIPetkova19 Jul 23, 2026
b964d82
Feature/104 add soft delete on faculty; Bug/105 Delete Major doesn't …
PIPetkova19 Jul 20, 2026
7c9ecbe
Add availableSeats column to Room entity, update dtos, repository met…
PIPetkova19 Jul 23, 2026
ab0c3e1
Make faculty optional for room
PIPetkova19 Jul 23, 2026
489f7f0
Add description field to category
PIPetkova19 Jul 23, 2026
2afbb6d
Add Building entity, update liquibase
PIPetkova19 Jul 23, 2026
cd3b649
Add room field to building
PIPetkova19 Jul 28, 2026
3768d12
Merge branch 'main' into enhancement/134-enhance-room-domain-model
PIPetkova19 Jul 28, 2026
3ba1f78
Merge branch 'main' into enhancement/134-enhance-room-domain-model
PIPetkova19 Aug 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/main/java/org/unilab/uniplan/building/Building.java

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are unused imports

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.unilab.uniplan.building;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.unilab.uniplan.common.model.BaseEntity;
import org.unilab.uniplan.room.Room;
import org.unilab.uniplan.university.University;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "building")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Building extends BaseEntity {

@Column(name = "name", nullable = false, length = 50)
private String name;

@Column(name = "address", nullable = false, length = 100)
private String address;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "university_id", referencedColumnName = "id")
private University university;

@OneToMany(mappedBy = "building")
private List<Room> rooms = new ArrayList<>();
}
4 changes: 4 additions & 0 deletions src/main/java/org/unilab/uniplan/category/Category.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public class Category extends BaseEntity {

@Column(name = "room_type", nullable = false, length = 50)
private String roomType;

@Column(name = "capacity", nullable = false)
private short capacity;

@Column(name = "description", nullable = true, length = 100)
private String description;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ public record CategoryDto(
String roomType,

@Positive
short capacity
short capacity,

@Size(min = 1, max = 100, message = "Description must be between 1 and 100 characters")
String description
) {

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.unilab.uniplan.category.dto;

import jakarta.persistence.Column;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.Size;
Expand All @@ -11,7 +12,10 @@ public record CategoryRequestDto(
String roomType,

@Positive
short capacity
short capacity,

@Size(min = 1, max = 100, message = "Description must be between 1 and 100 characters")
String description
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ public record CategoryResponseDto(
String roomType,

@Positive
short capacity
short capacity,

@Size(min = 1, max = 100, message = "Description must be between 1 and 100 characters")
String description
) {

}
14 changes: 14 additions & 0 deletions src/main/java/org/unilab/uniplan/room/CustomRoomRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.unilab.uniplan.room;

import org.springframework.data.repository.query.Param;
import org.unilab.uniplan.room.dto.RoomResponseDto;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

public interface CustomRoomRepository {

List<RoomResponseDto> findAllRoomResponses();

Optional<RoomResponseDto> findRoomResponseById(UUID id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.unilab.uniplan.room;

import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.hibernate.query.common.JoinType;
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.query.criteria.JpaCriteriaQuery;
import org.hibernate.query.criteria.JpaEntityJoin;
import org.hibernate.query.criteria.JpaRoot;
import org.springframework.data.repository.query.Param;
import org.unilab.uniplan.category.Category;
import org.unilab.uniplan.room.dto.RoomResponseDto;
import org.unilab.uniplan.roomcategory.RoomCategory;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

public class CustomRoomRepositoryImpl implements CustomRoomRepository {

@PersistenceContext
private EntityManager entityManager;

@Override
public List<RoomResponseDto> findAllRoomResponses() {
HibernateCriteriaBuilder cb = (HibernateCriteriaBuilder) entityManager.getCriteriaBuilder();

JpaCriteriaQuery<RoomResponseDto> query = cb.createQuery(RoomResponseDto.class);

JpaRoot<Room> room = query.from(Room.class);

JpaEntityJoin<Room, RoomCategory> roomCategory =
room.join(RoomCategory.class, JoinType.LEFT);
roomCategory.on(cb.equal(roomCategory.get("room"), room));

JpaEntityJoin<RoomCategory, Category> category =
roomCategory.join(Category.class, JoinType.LEFT);
category.on(cb.equal(category, roomCategory.get("category")));

query.select(cb.construct(
RoomResponseDto.class,
room.get("id"),
room.get("faculty").get("id"),
room.get("roomNumber"),
room.get("availableSeats"),
category.get("id"),
room.get("building").get("id")
));

return entityManager.createQuery(query).getResultList();
}

@Override
public Optional<RoomResponseDto> findRoomResponseById(UUID id) {
HibernateCriteriaBuilder cb = (HibernateCriteriaBuilder) entityManager.getCriteriaBuilder();

JpaCriteriaQuery<RoomResponseDto> query = cb.createQuery(RoomResponseDto.class);

JpaRoot<Room> room = query.from(Room.class);
JpaEntityJoin<Room, RoomCategory> roomCategory =
room.join(RoomCategory.class, JoinType.LEFT);
roomCategory.on(cb.equal(roomCategory.get("room"), room));

JpaEntityJoin<RoomCategory, Category> category =
roomCategory.join(Category.class, JoinType.LEFT);
category.on(cb.equal(category, roomCategory.get("category")));

query.select(cb.construct(
RoomResponseDto.class,
room.get("id"),
room.get("faculty").get("id"),
room.get("roomNumber"),
room.get("availableSeats"),
category.get("id"),
room.get("building").get("id")
)).where(cb.equal(room.get("id"), id));

return entityManager.createQuery(query)
.getResultStream()
.findFirst();
}
}
11 changes: 10 additions & 1 deletion src/main/java/org/unilab/uniplan/room/Room.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.unilab.uniplan.building.Building;
import org.unilab.uniplan.common.model.BaseEntity;
import org.unilab.uniplan.faculty.Faculty;

Expand All @@ -21,9 +23,16 @@
public class Room extends BaseEntity {

@ManyToOne
@JoinColumn(name = "faculty_id", referencedColumnName = "id", nullable = false)
@JoinColumn(name = "faculty_id", referencedColumnName = "id", nullable = true)
private Faculty faculty;

@Column(name = "room_number", nullable = false, length = 50)
private String roomNumber;

@Column(name = "available_seats", nullable = false)
private int availableSeats;

@ManyToOne
@JoinColumn(name = "building_id")
private Building building;
}
28 changes: 10 additions & 18 deletions src/main/java/org/unilab/uniplan/room/RoomController.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.unilab.uniplan.room;

import static org.springframework.http.ResponseEntity.ok;

import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
Expand All @@ -18,7 +16,6 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.unilab.uniplan.room.dto.RoomDto;
import org.unilab.uniplan.room.dto.RoomRequestDto;
import org.unilab.uniplan.room.dto.RoomResponseDto;

Expand All @@ -28,39 +25,34 @@
@Tag(name = "Rooms", description = "Manage classrooms and lecture halls, including room numbers and assigned faculties")
public class RoomController {

private final RoomService roomService;
private final RoomMapper roomMapper;
private final RoomWebFacade roomWebFacade;

@PostMapping
public ResponseEntity<RoomResponseDto> createRoom(@Valid @NotNull @RequestBody final RoomRequestDto roomRequestDto) {
final RoomDto roomDto = roomService.createRoom(roomMapper.toInternalDto(roomRequestDto));

return new ResponseEntity<>(roomMapper.toResponseDto(roomDto), HttpStatus.CREATED);
public ResponseEntity<Void> createRoom(@Valid @NotNull @RequestBody final RoomRequestDto roomRequestDto) {
roomWebFacade.createRoom(roomRequestDto);
return ResponseEntity.status(HttpStatus.CREATED).build();
}

@GetMapping
public List<RoomResponseDto> getAllRooms() {
return roomMapper.toResponseDtoList(roomService.getAllRooms());
public ResponseEntity<List<RoomResponseDto>> getAllRooms() {
return ResponseEntity.ok(roomWebFacade.getAllRooms());
}

@GetMapping("/{id}")
public ResponseEntity<RoomResponseDto> getRoomById(@PathVariable final UUID id) {
final RoomDto roomDto = roomService.getRoomById(id);

return ok(roomMapper.toResponseDto(roomDto));
return ResponseEntity.ok(roomWebFacade.getRoomById(id));
}

@PutMapping("/{id}")
public ResponseEntity<RoomResponseDto> updateRoom(@PathVariable final UUID id,
@Valid @NotNull @RequestBody final RoomRequestDto roomRequestDto) {
final RoomDto internalDto = roomMapper.toInternalDto(roomRequestDto);

return ok(roomMapper.toResponseDto(roomService.updateRoom(id, internalDto)));
roomWebFacade.updateRoom(id, roomRequestDto);
return ResponseEntity.noContent().build();
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteRoom(@PathVariable final UUID id) {
roomService.deleteRoom(id);
roomWebFacade.deleteRoom(id);

return ResponseEntity.noContent().build();
}
Expand Down
22 changes: 7 additions & 15 deletions src/main/java/org/unilab/uniplan/room/RoomMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,21 @@
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.unilab.uniplan.room.dto.RoomDto;
import org.unilab.uniplan.room.dto.RoomRequestDto;
import org.unilab.uniplan.room.dto.RoomResponseDto;

@Mapper
public interface RoomMapper {

@Mapping(source = "faculty.id", target = "facultyId")
RoomDto toDto(final Room room);
@Mapping(target = "faculty", ignore = true)
Room toEntity(final RoomRequestDto roomRequestDto);

@Mapping(source = "facultyId", target = "faculty.id")
Room toEntity(final RoomDto roomDto);
@Mapping(target = "facultyId", source = "faculty.id")
RoomResponseDto toResponseDto(Room room);

@Mapping(target = "id", ignore = true)
RoomDto toInternalDto(final RoomRequestDto roomRequestDto);

RoomResponseDto toResponseDto(final RoomDto roomDto);

List<RoomDto> toDtoList(final List<Room> rooms);

List<RoomResponseDto> toResponseDtoList(final List<RoomDto> rooms);
List<RoomResponseDto> toResponseDtoList(final List<Room> rooms);

@Mapping(source = "roomDto.facultyId", target = "faculty.id")
@Mapping(target = "faculty", ignore = true)
@Mapping(target = "id", ignore = true)
void updateEntityFromDto(final RoomDto roomDto, @MappingTarget final Room room);
void updateEntityFromDto(final RoomRequestDto roomRequestDto, @MappingTarget final Room room);
}
3 changes: 1 addition & 2 deletions src/main/java/org/unilab/uniplan/room/RoomRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@
import org.springframework.stereotype.Repository;

@Repository
public interface RoomRepository extends JpaRepository<Room, UUID> {

public interface RoomRepository extends JpaRepository<Room, UUID>, CustomRoomRepository {
}
Loading
Loading