我正在创建一个具有以下实体的酒店预订 API。
酒店.java
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.HashSet;
import java.util.Set;
@NoArgsConstructor
@AllArgsConstructor
@Data
@Entity
public class Hotel {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
Long id;
// other fields
@OneToMany(mappedBy = "hotel", cascade = CascadeType.ALL)
Set<Room> rooms = new HashSet<>();
}
房间.java
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Data
@Entity
public class Room {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
Long id;
// other fields
@ManyToOne
@JoinColumn(name = "hotel_id")
Hotel hotel;
}
HotelRepository.java
import com.hotel.api.booking.model.Hotel;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface HotelRepository extends JpaRepository<Hotel, Long> {
}
在控制器内,我尝试使用下面的代码删除酒店实体
@Transactional
@PreAuthorize("hasAuthority('ADMIN')")
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
public EntityCreatedDTO deleteHotel(@PathVariable Long id) {
Hotel targetHotel = hotelRepo.findById(id).orElseThrow();
hotelRepo.delete(targetHotel);
return new EntityCreatedDTO(targetHotel.getId(), "Hotel deleted successfully");
}
当我向上述端点发送删除请求时,我收到 403 Forbidden,并出现以下异常。
org.postgresql.util.PSQLException: ERROR: update or delete on table "hotel" violates foreign key constraint "fkdosq3ww4h9m2osim6o0lugng8" on table "room"
Detail: Key (id)=(1) is still referenced from table "room".
我将 show-sql 属性设置为 true。这是创建关系的 DDL 查询 hibernate 问题。
alter table if exists room
add constraint FKdosq3ww4h9m2osim6o0lugng8
foreign key (hotel_id)
references hotel
没有级联属性的迹象 ́\(ツ)/́
我已经有了解决办法,我只是想知道为什么?
谢谢:)
Cascade
与数据库中外键约束的 cascade
选项完全无关。这意味着定义不会转换为 DDL,它们告诉 Hibernate 在执行操作时如何表现。
我的意见是用所有员工的模型创建第一个数据库(PK、FK、约束、
cascade
…),然后将其转换为实体(JPA/Hibernate)
这是生产项目的最佳方法。