JPA 错误:InvalidDataAccessApiUsageException:

我有两个实体使用oneToMany注释相互映射。一个实体是bookedBus,第二个是drivers驱动程序实体已经插入了一行,该行稍后将成为bookedBus 实体(PK) 的外部引用(FK)。下面是两个实体,为简洁起见,setter 和 getter 已被跳过。


第一个实体


@Entity

@Table(name = "bookedBuses")

public class BookedBuses implements Serializable {


    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)

    private Long id;


    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)

    @JoinColumn(name = "driver_id")

    private Drivers driver;

}

第二实体


@Entity

public class Drivers implements Serializable {


    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)

    private Long id;


    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "driver")

    private List<BookedBuses> bookedBus;

}

现在,当我尝试保存到预订的巴士实体时,它会引发以下异常


org.springframework.dao.InvalidDataAccessApiUsageException:分离的实体传递给坚持:com.bus.api.entity.Drivers;嵌套异常是 org.hibernate.PersistentObjectException:分离的实体传递给坚持:com.bus.api.entity.Drivers


以下是我尝试保存到bookedBus 实体的方法


BookedBuses bookedRecord = new BookedBuses();

bookedRecord.setBookedSeats(1);

bookedRecord.setBookedBusState(BookedBusState.LOADING);

      bookedRecord.setBus(busService.getBusByPlateNumber(booking.getPlateNumber()));

bookedRecord.setRoute(booking.getRoute());

 infoLogger.info("GETTING DRIVER ID ======= " +    booking.getDriver().getId());

 Drivers drivers = new Drivers(booking.getDriver().getId());

 List<BookedBuses> d_bu = new ArrayList<>();

 drivers.setBooked(d_bu);

 drivers.addBooked(bookedRecord);

 bookedRecord.setDriver(drivers);

 bookedBusService.save(bookedRecord);

My BookBusService 按要求保存方法


@Autowired

private BookedBusRepository bookedBusRepo;

public boolean save(BookedBuses bookedRecord) {

    try {

        bookedBusRepo.save(bookedRecord);

        return true;

    } catch (DataIntegrityViolationException ex) {

        System.out.println(ex);

        AppConfig.LOGGER.error(ex);

        return false;

        // Log error message

    }

}


小唯快跑啊
浏览 297回答 2
2回答

慕桂英546537

第一个你在命名上有一些混淆:你有Driver&&nbsp;Drivers。像这样:private&nbsp;Drivers&nbsp;driver;还选择这样的变量名称:BookedBuses&nbsp;bookedRecord&nbsp;=&nbsp;new&nbsp;BookedBuses();会造成很多混乱。不要在类型之间混合复数和单数,最好不要引入可能不容易关联的名称,如记录。还有这个:private&nbsp;List<BookedBuses>&nbsp;bookedBus;应该是这样的:private&nbsp;List<BookedBus>&nbsp;bookedBuses;(并且还需要更改您的班级名称 BookedBus -> BookedBus)无论如何,实际问题似乎在这里:Drivers&nbsp;drivers&nbsp;=&nbsp;new&nbsp;Drivers(booking.getDriver().getId());您需要在存储库的帮助下按 id 获取现有实体,而不是使用现有的 id 创建一个新实体。所以像:Drivers&nbsp;drivers&nbsp;=&nbsp;driverRepo.findOne(booking.getDriver().getId());&nbsp;//&nbsp;or&nbsp;findById(..)似乎您有一个构造函数(您没有显示),可以创建具有 id 的驱动程序。没有管理它被认为是分离的。(你也有drivers.addBooked(bookedRecord);你没有分享的,但也许是微不足道的)另请注意,一些帖子建议根据您的需要更改CascadeType.ALL是否CascadeType.MERGE有效。Spring 数据能够save(..)基于实体 id 进行一些合并,但在这种情况下不一定。

幕布斯7119047

这条线Drivers drivers = new Drivers(booking.getDriver().getId());如果您已经拥有可用的驱动程序 ID,则无需再次从数据库中提取驱动程序 ID。从&中删除Cascade属性后,您的代码应该可以工作。@OneToMany@ManyToOne@Entity@Table(name = "bookedBuses")public class BookedBuses implements Serializable {&nbsp; &nbsp; @Id&nbsp; &nbsp; @GeneratedValue(strategy = GenerationType.IDENTITY)&nbsp; &nbsp; private Long id;`&nbsp; &nbsp; @ManyToOne(fetch = FetchType.LAZY)&nbsp; &nbsp; @JoinColumn(name = "driver_id")&nbsp; &nbsp; private Drivers driver;}@Entitypublic class Drivers implements Serializable {&nbsp; &nbsp; @Id&nbsp; &nbsp; @GeneratedValue(strategy = GenerationType.IDENTITY)&nbsp; &nbsp; private Long id;&nbsp; &nbsp; @OneToMany(fetch = FetchType.LAZY)&nbsp; &nbsp; @JoinColumn(name = "driver_id")&nbsp; &nbsp; private List<BookedBuses> bookedBus;}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java