簡體   English   中英

如何在 oneToMany 關系中正確創建新子項以避免托管刷新和分離實體錯誤? 【Spring+PostgreSQL】

[英]How to properly create a new child in oneToMany relationship to avoid managed flush and detached entity errors? [Spring+PostgreSQL]

預訂系統涉及實體:用戶、預訂、課程。
問題: ReservationService 不會將預訂添加到數據庫或用戶。 Reservation 預訂的自動生成的 long id = new Reservation(); 是 0 [我試過序列生成類型,沒用]。 然后,reservationService.addReservation(reservation); 導致錯誤:分離的實體傳遞給持久化。 關系:

用戶 -- oneToMany --> 預訂 -- oneToOne --> 課程

預訂控制器:

@Controller
public class ReservationController {

    private final AppUserService appUserService;
    private final ReservationService reservationService;
    private final CourseService courseService;

    public ReservationController(AppUserService appUserService, ReservationService reservationService, CourseService courseService) {
        this.appUserService = appUserService;
        this.reservationService = reservationService;
        this.courseService = courseService;
    }

    @RequestMapping(value = "bookCourse/{courseId}")
    public String bookCourse(@PathVariable("courseId") long id, Principal principal) {

        AppUser user = appUserService.getAppUser(principal.getName());
        Course course = courseService.getCourse(id);

        Reservation reservation = new Reservation();

        reservation.setAppUser(user);
        reservation.setCourse(course);

        reservationService.addReservation(reservation);

        user.getReservations().add(reservation); //this line causes the error:       
        //org.hibernate.PersistentObjectException: detached entity passed to persist: application.domain.Course

        appUserService.editAppUser(user);

        return "redirect:/reservations.html";
    }

預訂服務實施:

@Service("reservationService")
@Transactional
public class ReservationServiceImpl implements ReservationService {

    private final ReservationRepository reservationRepository;

    @Autowired
    public ReservationServiceImpl(ReservationRepository reservationRepository) {
        this.reservationRepository = reservationRepository;
    }

    @Transactional
    public void addReservation(Reservation reservation) {
        reservationRepository.save(reservation);
    };

用戶.java:

@Entity
@Table(name="appuser")
public class AppUser {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    long id;

    @OneToMany(mappedBy="appUser", cascade = CascadeType.ALL)
    private Set<Reservation> reservations;

    //getters and setters
}

預訂.java:

@Entity
@Table(name="reservation")
public class Reservation {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @OneToOne(cascade = CascadeType.ALL)
    @JsonManagedReference
    private Course course;

    @ManyToOne(fetch = FetchType.EAGER)//(mappedBy="reservation")
    private AppUser appUser;

    //getters and setters

課程.java:

@Entity
@Table(name="course")
public class Course {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @NotEmpty
    private String name;

    @NotEmpty
    private String price;

    @JsonBackReference
    @OneToOne(mappedBy="course")
    private Reservation reservation;
   
    //getters and setters

在數據庫中,已經創建了一個 appuser_reservation 聯結表來鏈接用戶和預訂的 ID。
在數據庫中,reservation 具有“自動”創建的 appuser_id 和 course_id,並且是 bigint 類型。

通過單擊課程列表 html 來引用 ReservationController 方法:

<a href="bookCourse/${course.id}">Book!</a> 

[課程已經在數據庫中]

框架是Spring,數據庫是PostgreSQL。

如果需要更多信息,請告訴我!

由於我不知道問題是否是 new Reservation() 創建了一個具有空 ID 的預訂,因此服務無法將其正確保存到 DB,或者還有其他一些更普遍的問題,我不知道不知道這個問題的標題是否合適。

我知道錯誤本身已經被討論過,但我現在好幾天都無法解決這個問題,我將非常感謝所有的洞察力。 也許我在理解關系或 new Entity() 的工作方式方面犯了一個錯誤。

在 bookCourse{id} 中創建一個新的 Reservation() 有什么問題; 並將其寫入數據庫?

好的,我們親自見面並解決了問題。

與 JPA 和 Hibernate 的關系是錯誤的。
您需要將 Reservation 中的關系更改為:

@Entity
@Table(name="reservation")
public class Reservation { 
...
@ManyToOne
private Course course;
...
}

你在這里有一個現場繪圖,所以你可以記住什么是什么以及關系是什么。 現場繪圖

預訂預訂的自動生成的長 ID = new Reservation(); 是 0

首先,您需要將創建的實體添加到數據庫並獲取它以獲取自動生成的 id,如下所示:

Reservation reservation = new Reservation();  
// fill the reservation

// I assume there is repository.save(reservation); 
Reservation reservationWithID = reservationService.add(reservation);

// assign reservationWithID to User Reservation List to create connection

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM