diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/BookingController.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/BookingController.java
index 5677526ffade16bc0298de537cdf9f42f79c8213..b3b78e3543d2dd533c1423d27c5e2e291552a729 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/BookingController.java
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/BookingController.java
@@ -2,19 +2,30 @@
 package com.uva.roomBooking.Controllers;
 
 import com.uva.roomBooking.Models.Booking;
+import com.uva.roomBooking.Models.Room;
+import com.uva.roomBooking.Models.User;
 import com.uva.roomBooking.Repositories.BookingRepository;
+import com.uva.roomBooking.Repositories.RoomRepository;
+import com.uva.roomBooking.Repositories.UserRepository;
+
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
 @RestController
 @RequestMapping("/bookings")
+@CrossOrigin(origins = "http://localhost:4200")
 public class BookingController {
 
     private final BookingRepository bookingRepository;
+    private final UserRepository userRepository;
+    private final RoomRepository roomRepository;
 
-    public BookingController(BookingRepository bookingRepository) {
+    public BookingController(BookingRepository bookingRepository, UserRepository userRepository,
+            RoomRepository roomRepository) {
         this.bookingRepository = bookingRepository;
+        this.userRepository = userRepository;
+        this.roomRepository = roomRepository;
     }
 
     @GetMapping
@@ -24,6 +35,10 @@ public class BookingController {
 
     @PostMapping
     public Booking createBooking(@RequestBody Booking booking) {
+        User user = userRepository.findById(booking.getUserId().getId()).orElseThrow();
+        Room room = roomRepository.findById(booking.getRoomId().getId()).orElseThrow();
+        booking.setUserId(user);
+        booking.setRoomId(room);
         return bookingRepository.save(booking);
     }
 
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/HotelController.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/HotelController.java
index a4dae001f04d3eb9af97d609275634f86e4f31e6..4739c7343d804c472f691636481e7dd3f7a208d4 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/HotelController.java
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/HotelController.java
@@ -3,90 +3,98 @@ package com.uva.roomBooking.Controllers;
 import java.util.List;
 import java.time.LocalDate;
 
+import com.uva.roomBooking.Exceptions.HotelNotFoundException;
+import com.uva.roomBooking.Exceptions.InvalidDateRangeException;
 import com.uva.roomBooking.Models.Hotel;
 import com.uva.roomBooking.Models.Room;
 import com.uva.roomBooking.Repositories.HotelRepository;
 import com.uva.roomBooking.Repositories.RoomRepository;
 
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-
-// TODO incluir excepciones y procesado de respuestas con entidad y código de estado
-
 @RestController
 @RequestMapping("hotels")
 @CrossOrigin(origins = "*")
 public class HotelController {
-  private final HotelRepository hotelRepository;
-  private final RoomRepository roomRepository;
-
-  public HotelController(HotelRepository hotelRepository, RoomRepository roomRepository) {
-    this.hotelRepository = hotelRepository;
-    this.roomRepository = roomRepository;
-  }
-
-  @GetMapping
-  public List<Hotel> getAllHotels() {
-    return hotelRepository.findAll();
-  }
-
-  @PostMapping
-  public Hotel addHotel(@RequestBody Hotel hotel) {
-    // TODO comprobar y asegurar que se agregan todas sus habitaciones también
-    return hotelRepository.save(hotel);
-  }
-
-  @GetMapping("/{id}")
-  public Hotel getHotelById(@PathVariable int id) {
-    return hotelRepository.findById(id).orElse(null);
-  }
-
-  @DeleteMapping("/{id}")
-  public Hotel deleteHotel(@PathVariable Integer id) {
-    Hotel target;
-    if ((target = hotelRepository.findById(id).orElse(null)) != null) {
-      // TODO asegurarse de que el borrado es en CASCADA -> Hotel y habitaciones
-      hotelRepository.deleteById(id);
+    private final HotelRepository hotelRepository;
+    private final RoomRepository roomRepository;
+
+    public HotelController(HotelRepository hotelRepository, RoomRepository roomRepository) {
+        this.hotelRepository = hotelRepository;
+        this.roomRepository = roomRepository;
+    }
+
+    // Obtener todos los hoteles
+    @GetMapping
+    public List<Hotel> getAllHotels() {
+        return hotelRepository.findAll();
+    }
+
+    // Añadir un hotel con sus habitaciones
+    @PostMapping
+    public ResponseEntity<Hotel> addHotel(@RequestBody Hotel hotel) {
+        Hotel savedHotel = hotelRepository.save(hotel);
+        return new ResponseEntity<>(savedHotel, HttpStatus.CREATED);
+    }
+
+    // Obtener un hotel por su ID
+    @GetMapping("/{id}")
+    public Hotel getHotelById(@PathVariable int id) {
+        return hotelRepository.findById(id)
+                .orElseThrow(() -> new HotelNotFoundException(id));
+    }
+
+    // Borrar un hotel junto con sus habitaciones (borrado en cascada)
+    @DeleteMapping("/{id}")
+    public ResponseEntity<Void> deleteHotel(@PathVariable Integer id) {
+        Hotel target = hotelRepository.findById(id)
+                .orElseThrow(() -> new HotelNotFoundException(id));
+        hotelRepository.delete(target);
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+    }
+
+    // Obtener habitaciones de un hotel según disponibilidad y fechas
+    @GetMapping("/{hotelId}/rooms")
+    public ResponseEntity<List<Room>> getRoomsFromHotel(
+            @PathVariable int hotelId,
+            @RequestParam(required = false) LocalDate date1,
+            @RequestParam(required = false) LocalDate date2) {
+
+        List<Room> rooms;
+        if (date1 != null && date2 != null) {
+            if (!date1.isBefore(date2)) {
+                throw new InvalidDateRangeException("La fecha de inicio debe ser anterior a la fecha de fin");
+            }
+            rooms = roomRepository.findAvailableRoomsByHotelAndDates(hotelId, date1, date2);
+        } else {
+            rooms = roomRepository.findAllByHotelId(hotelId);
+        }
+        return new ResponseEntity<>(rooms, HttpStatus.OK);
+    }
+
+    // Actualizar disponibilidad de una habitación específica en un hotel
+    @PatchMapping("/{hotelId}/rooms/{roomId}")
+    public ResponseEntity<Room> updateRoomAvailability(
+            @PathVariable int hotelId,
+            @PathVariable int roomId,
+            @RequestBody boolean available) {
+
+        Room targetRoom = roomRepository.findByIdAndHotelId(roomId, hotelId)
+                .orElseThrow(() -> new IllegalArgumentException("Habitación no encontrada"));
+
+        targetRoom.setAvailable(available);
+        roomRepository.save(targetRoom);
+
+        return new ResponseEntity<>(targetRoom, HttpStatus.OK);
+    }
+
+    // Obtener los detalles de una habitación específica en un hotel
+    @GetMapping("/{hotelId}/rooms/{roomId}")
+    public Room getRoomByIdFromHotel(
+            @PathVariable int hotelId, @PathVariable int roomId) {
+        return roomRepository.findByIdAndHotelId(roomId, hotelId)
+                .orElseThrow(() -> new HotelNotFoundException(hotelId));
     }
-    return target;
-  }
-
-  // TODO completar controllers de rooms
-  @GetMapping("/{id}/rooms")
-  // Dejo un esqueleto, a lo mejor sería mejor otra forma de plantear el manejo y
-  // recogida de query params
-  public List<Room> getRoomsFromHotel(@PathVariable int hotelId, @RequestParam LocalDate date1,
-      @RequestParam LocalDate date2) {
-    throw new IllegalStateException("Not implemented yet");
-  }
-
-  @PatchMapping("/{id}/rooms")
-  public List<Room> updateRoomAvailabilityFromHotel(@PathVariable int hotelId) {
-    throw new IllegalStateException("Not implemented yet");
-  }
-
-  @GetMapping("/{hotelId}/rooms/{roomId}")
-  public List<Room> getRoomByIdFromHotel(@PathVariable int hotelId, @PathVariable int roomId) {
-    throw new IllegalStateException("Not implemented yet");
-  }
-
-  // Te dejo esto de la otra clase comentado por si te sirve algo
-
-  // @GetMapping
-  // public List<Room> getAllRooms() {
-  // return roomRepository.findAll();
-  // }
-
-  // @PostMapping
-  // public Room addRoom(@RequestBody Room room) {
-  // return roomRepository.save(room);
-  // }
-
-  // @DeleteMapping("/{id}")
-  // public void deleteRoom(@PathVariable Integer id) {
-  // roomRepository.deleteById(id);
-  // }
-
-}
\ No newline at end of file
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/GlobalExceptionHandler.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/GlobalExceptionHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..03b21e27ffa7e4e921cc9801187911d9f1be6a52
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/GlobalExceptionHandler.java
@@ -0,0 +1,50 @@
+package com.uva.roomBooking.Exceptions;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Map;
+
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+    @ExceptionHandler(HotelNotFoundException.class)
+    public ResponseEntity<Map<String, Object>> handleHotelNotFound(HotelNotFoundException ex) {
+        Map<String, Object> body = new HashMap<>();
+        body.put("timestamp", LocalDateTime.now());
+        body.put("message", ex.getMessage());
+
+        return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
+    }
+
+    @ExceptionHandler(InvalidRequestException.class)
+    public ResponseEntity<Map<String, Object>> handleInvalidRequest(InvalidRequestException ex) {
+        Map<String, Object> body = new HashMap<>();
+        body.put("timestamp", LocalDateTime.now());
+        body.put("message", ex.getMessage());
+
+        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
+    }
+
+    @ExceptionHandler(InvalidDateRangeException.class)
+    public ResponseEntity<Map<String, Object>> handleInvalidDateRange(InvalidDateRangeException ex) {
+        Map<String, Object> body = new HashMap<>();
+        body.put("timestamp", LocalDateTime.now());
+        body.put("message", ex.getMessage());
+
+        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
+    }
+
+    @ExceptionHandler(Exception.class)
+    public ResponseEntity<Map<String, Object>> handleGeneralException(Exception ex) {
+        Map<String, Object> body = new HashMap<>();
+        body.put("timestamp", LocalDateTime.now());
+        body.put("message", "An unexpected error occurred: " + ex.getMessage());
+
+        return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
+    }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/HotelNotFoundException.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/HotelNotFoundException.java
new file mode 100644
index 0000000000000000000000000000000000000000..3d47f5efad71b6fbf3b3f5912493c9c0af1ca412
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/HotelNotFoundException.java
@@ -0,0 +1,11 @@
+package com.uva.roomBooking.Exceptions;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(HttpStatus.NOT_FOUND)  // Devuelve un 404 cuando se lanza la excepción
+public class HotelNotFoundException extends RuntimeException {
+    public HotelNotFoundException(int id) {
+        super("Hotel not found with id: " + id);
+    }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidDateRangeException.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidDateRangeException.java
new file mode 100644
index 0000000000000000000000000000000000000000..17a8420453ef402411b61b965d001560a4dd51ce
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidDateRangeException.java
@@ -0,0 +1,8 @@
+package com.uva.roomBooking.Exceptions;
+
+public class InvalidDateRangeException extends RuntimeException {
+    public InvalidDateRangeException(String message) {
+        super(message);
+    }
+}
+
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidRequestException.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidRequestException.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8433b6f620da742dab87dae96a2e0f0193709ff
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidRequestException.java
@@ -0,0 +1,11 @@
+package com.uva.roomBooking.Exceptions;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(HttpStatus.BAD_REQUEST)
+public class InvalidRequestException extends RuntimeException {
+    public InvalidRequestException(String message) {
+        super(message);
+    }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Booking.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Booking.java
index 573bde806cf28ffba375f41331b8f32bdc8d9715..c2b36c948f72392174dcf1ebdcb7c4face3303ef 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Booking.java
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Booking.java
@@ -2,8 +2,6 @@ package com.uva.roomBooking.Models;
 
 import java.util.Date;
 
-import com.fasterxml.jackson.annotation.JsonIgnore;
-
 import jakarta.persistence.Basic;
 import jakarta.persistence.CascadeType;
 import jakarta.persistence.Column;
@@ -24,21 +22,25 @@ public class Booking {
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     @Basic(optional = false)
     private int id;
+    // TODO revisar si lo de cascade es estrictamente necesario
     @JoinColumn(name = "user_id", referencedColumnName = "id")
-    @ManyToOne(optional = false, fetch = FetchType.LAZY)
+    @ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
     private User userId;
     @JoinColumn(name = "room_id", referencedColumnName = "id")
-    @ManyToOne(optional = false, fetch = FetchType.LAZY)
-    private Room roomID;
+    @ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
+    private Room roomId;
     @Column(name = "start_date", nullable = false)
-    private Date startDate;
+    private LocalDate startDate;
     @Column(name = "end_date", nullable = false)
-    private Date endDate;
+    private LocalDate endDate;
+
+    public Booking() {
+    }
 
-    public Booking(int id, User userId, Room roomID, Date startDate, Date endDate) {
+    public Booking(int id, User userId, Room roomID, LocalDate startDate, LocalDate endDate) {
         this.id = id;
         this.userId = userId;
-        this.roomID = roomID;
+        this.roomId = roomID;
         this.startDate = startDate;
         this.endDate = endDate;
     }
@@ -51,35 +53,36 @@ public class Booking {
         return this.id;
     }
 
-    public void setUser(User userId) {
+    public void setUserId(User userId) {
         this.userId = userId;
     }
 
-    public User getUser() {
+    public User getUserId() {
         return this.userId;
     }
 
-    public void setRoom(Room roomID) {
-        this.roomID = roomID;
+    public void setRoomId(Room roomID) {
+        this.roomId = roomID;
     }
 
-    public Room getRoom() {
-        return this.roomID;
+    public Room getRoomId() {
+        return this.roomId;
     }
 
-    public void setStartDate(Date startDate) {
+    public void setStartDate(LocalDate startDate) {
         this.startDate = startDate;
     }
 
-    public Date getStartDate() {
+    public LocalDate getStartDate() {
         return this.startDate;
     }
 
-    public void setEndDate(Date endDate) {
+    public void setEndDate(LocalDate endDate) {
         this.endDate = endDate;
     }
 
-    public Date getEndDate() {
+    public LocalDate getEndDate() {
         return this.endDate;
     }
+
 }
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Hotel.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Hotel.java
index 29e4e94ed076c53eed8628856cc93af80a36090a..5a23005de99c022b5fff9570e2c515fcfc75e07e 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Hotel.java
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Hotel.java
@@ -35,7 +35,7 @@ public class Hotel {
   @OneToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
   private Address address;
 
-  @OneToMany(mappedBy = "hotelId", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+  @OneToMany(mappedBy = "hotel", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
   private List<Room> rooms;
 
   public Hotel() {
@@ -78,7 +78,7 @@ public class Hotel {
 
   public void setRooms(List<Room> rooms) {
     this.rooms = rooms;
-    rooms.forEach(room -> room.setHotelId(this));
+    rooms.forEach(room -> room.setHotel(this));
   }
 
 }
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Room.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Room.java
index b03b0b6469ae0ea504bb4efa2e457bc6890d6990..7919e3643add4b380472b348e7100fb8e6742975 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Room.java
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Room.java
@@ -32,7 +32,7 @@ public class Room {
     @ManyToOne
     @JoinColumn(name = "hotel_id", referencedColumnName = "id")
     @JsonIgnore
-    private Hotel hotelId;
+    private Hotel hotel;
     @Column(name = "room_number", nullable = false)
     private int roomNumber;
     @Column(name = "type", nullable = false)
@@ -40,7 +40,7 @@ public class Room {
     @Column(name = "available", nullable = false)
     private boolean available;
     @JsonIgnore
-    @OneToMany(mappedBy = "roomID", fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
+    @OneToMany(mappedBy = "roomId", fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
     private List<Booking> bookings;
 
     public Room() {
@@ -48,7 +48,7 @@ public class Room {
 
     public Room(int id, Hotel hotelId, int roomNumber, Tipo type, boolean available, List<Booking> bookings) {
         this.id = id;
-        this.hotelId = hotelId;
+        this.hotel = hotelId;
         this.roomNumber = roomNumber;
         this.type = type;
         this.available = available;
@@ -63,12 +63,12 @@ public class Room {
         return this.id;
     }
 
-    public void setHotelId(Hotel hotelId) {
-        this.hotelId = hotelId;
+    public void setHotel(Hotel hotelId) {
+        this.hotel = hotelId;
     }
 
-    public Hotel getHotelId() {
-        return this.hotelId;
+    public Hotel getHotel() {
+        return this.hotel;
     }
 
     public void setRoomNumber(int roomNumber) {
@@ -91,7 +91,7 @@ public class Room {
         this.available = available;
     }
 
-    public boolean getAvailable() {
+    public boolean isAvailable() {
         return this.available;
     }
 
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/RoomRepository.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/RoomRepository.java
index 2ab8752620e9a982ded2b26a02f70a4463b48b0b..71b439ff3db90f48caa5ed5fbea6df89d44bd02e 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/RoomRepository.java
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/RoomRepository.java
@@ -1,8 +1,32 @@
-// RoomRepository.java
 package com.uva.roomBooking.Repositories;
 
 import com.uva.roomBooking.Models.Room;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Optional;
 
 public interface RoomRepository extends JpaRepository<Room, Integer> {
+
+    Optional<Room> findByIdAndHotelId(int id, int hotelId);
+
+    // Encontrar todas las habitaciones de un hotel
+    List<Room> findAllByHotelId(int hotelId);
+
+    // Encontrar habitaciones disponibles de un hotel en un rango de fechas
+    // TODO revisar los límites en las fechas
+    @Query("""
+                SELECT r FROM Room r
+                WHERE r.hotel.id = ?1
+                AND r.available = true
+                AND NOT EXISTS (
+                    SELECT b FROM Booking b
+                    WHERE b.roomId.id = r.id
+                    AND (b.startDate < ?3 AND b.endDate > ?2)
+                )
+            """)
+    List<Room> findAvailableRoomsByHotelAndDates(
+            int hotelId, LocalDate startDate, LocalDate endDate);
 }
diff --git a/java/roomBooking/src/main/resources/application.properties b/java/roomBooking/src/main/resources/application.properties
index 4331f85f147bc141240304d915c1820829a7768f..e111b6dcf5ce04ef32bd59b8d7c15b7fc35dc407 100644
--- a/java/roomBooking/src/main/resources/application.properties
+++ b/java/roomBooking/src/main/resources/application.properties
@@ -4,4 +4,7 @@ spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
 spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/RoomsBooking?createDatabaseIfNotExist=true
 spring.datasource.username=user
 spring.datasource.password=password
-spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
\ No newline at end of file
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+
+# Usar esto para alternar entre las exposición del room repository ya que no es necesario su uso pero por defecto, al no cubrir su ruta, se expone
+spring.data.rest.base-path=false
\ No newline at end of file