java - JPA错误: InvalidDataAccessApiUsageException: detached entity passed to persist

标签 java spring hibernate jpa

我有两个使用 oneToMany 注释相互映射的实体。第一个实体是 bookedBus,第二个实体是 drivers 驱动程序实体中已经插入了一行,该行稍后将成为 bookingBus 实体 (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: detached entity passed to persist: com.bus.api.entity.Drivers; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.bus.api.entity.Drivers

下面是我尝试保存到 bookingBus 实体的方法

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);

根据要求我的 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
    }
}

最佳答案

首先,您的命名有些困惑:您有 DriverDrivers。像这样:

private Drivers driver;

还选择这样的变量名称:

BookedBuses bookedRecord = new BookedBuses();

会引起很多困惑。不要在类型之间混合复数和单数,最好也不要引入可能不容易关联的名称(如记录)。还有这个:

private List<BookedBuses> bookedBus;

应该是这样的:

private List<BookedBus> bookedBuses;

(并且还需要更改您的类名 BookedBus -> BookedBus)

无论如何,实际问题似乎出在这里:

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

您需要在存储库的帮助下通过 id 获取现有实体,而不是使用现有 id 创建一个新实体。所以类似:

Drivers drivers = driverRepo.findOne(booking.getDriver().getId()); // or findById(..)

您似乎有一个构造函数(您没有显示)可以使用 id 创建驱动程序。不受管理的它被认为是分离的。 (您还有 drivers.addBooked(bookedRecord); 您没有共享它,但也许它是微不足道的)

另请注意一些帖子建议将CascadeType.ALL更改为CascadeType.MERGE是否有效取决于您的需求。 Spring data 能够根据实体 id 对 save(..) 进行一些合并,但在本例中不一定如此。

关于java - JPA错误: InvalidDataAccessApiUsageException: detached entity passed to persist,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54405522/

相关文章:

java - 如何在不实现可序列化的情况下在 spring-struts web 应用程序中将 DTO 对象从客户端传输到服务器

java - 升级到 Hibernate 5 时 SessionFactoryImpl 中的 AbstractMethodError

java - @Autowired 不起作用

java - Hibernate 只加载列表中的一个对象

mysql - COLLATION 'utf8_general_ci' 对于字符集 'latin1' 无效 - 即使设置了 utf8

java - 获取局部变量

java - 查看我们从 jar 文件导入的类内部有什么

java - 尝试打印并获取 : "cannot be resolved to a variable" error

java - 滚动()和添加()

java - 将 Controller 端点映射到 Spring JPA 层