当前位置: 首页 > 知识库问答 >
问题:

JPA错误:InvalidDataAccessApiUsage异常:传递到持久化的分离实体

鄢选
2023-03-14

我使用oneToMany注释将两个实体相互映射。一个实体是bookedBus,第二个实体是drivers。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;
}

现在当我尝试保存到已预订的总线实体时,它会抛出以下异常

组织。springframework。刀。InvalidDataAccessApiUsageException:传递给persist:com的分离实体。公共汽车应用程序编程接口。实体司机;嵌套的异常是org。冬眠PersistentObjectException:传递给persist:com的分离实体。公共汽车应用程序编程接口。实体司机

下面是我如何尝试保存到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);

我的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
    }
}

共有2个答案

蔺弘
2023-03-14

这条线

驱动程序=新的驱动程序(booking.get驱动程序(). getId());

如果您已经拥有可用的驱动程序ID,则无需再次从数据库中提取驱动程序ID。

删除@OneToMore中的Cascade属性后

@Entity
@Table(name = "bookedBuses")
public class BookedBuses implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
`
    @ManyToOne(fetch = FetchType.LAZY)
    @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)
    @JoinColumn(name = "driver_id")
    private List<BookedBuses> bookedBus;
}
隆睿
2023-03-14

首先,你在命名上有些混乱:你有驱动程序

private Drivers driver;

还可以选择如下变量名:

BookedBuses bookedRecord = new BookedBuses();

会造成很多混乱。不要混合复数

private List<BookedBuses> bookedBus;

应该是这样的:

private List<BookedBus> bookedBuses;

(我亦会否要求更改你的类别名称BookedBuse-

不管怎样,实际问题似乎就在这里:

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

您需要在repository的帮助下按id获取现有实体,而不是创建id为existing的新实体。比如:

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

似乎您有一个构造函数(您没有显示),可以创建一个id为的驱动程序。如果没有管理,则认为它是分离的。(您还有drivers.addBooked(bookedRecord) 你没有分享,但可能很琐碎)

请注意,一些帖子建议更改cascade类型。所有级联类型。合并这是否有效取决于您的需要。Spring数据可以在save(…)上进行一些合并 基于实体id,但在本例中不一定如此。

 类似资料:
  • 我用的是JPA。 在数据库中,有建筑表和房间表。它们有一个OneTo多连接。 我可以将数据添加到建筑中,但当我尝试将数据添加到房间中时,会出现错误: 我的建筑模型: 我的房间模型: 我的主应用。在这里,我获取建筑对象并将其传递到房间: 请帮忙。

  • 我有一个实体,它已经持久化,并希望将其添加到新生成的父实体(尚未持久化)。如果我尝试持久化父级,我会得到错误“分离的实体传递到持久化:model.child”。我想我必须以某种方式为孩子调用“EntityManager.merge()”,而不是“EntityManager.persisted()”。但是我没有显式调用persisted。这由“cascade=cascadetype.all”注释处理

  • 问题内容: 我正在尝试使用Hibernate EntityManagerpersist方法将个人pojo插入mysql db, 得到这个例外 还有更多.. 我的Person.java类是, 然后是pojo的getter setter方法。 引发TitleType类的错误是“公共静态最终”标题类型定义提供程序, 我正在为人员设置标题类型类, 不可能将公共静态最终类型定义的类传递给Hibernate?

  • 我正试图实现与hibernate的许多单向关系。问题是,当我试图向数据库中添加一些值时,我遇到了以下错误: 运行时发生异常。null:InvocationTargetException:未能执行ApplicationRunner:传递给persist:dnd35cg的分离实体。模型DND类;嵌套的异常是org。冬眠PersistentObjectException:传递给persist:dnd35

  • 问题内容: 我正在创建一个简单的应用程序,只需使用将一行插入到表中(如果表不存在,则创建它)。 我为它的一个可运行示例附加了一些代码。 这是我得到的异常和stacktrace: 这是我的代码: 主班: 和Person类: 这是我的persistence.xml文件 -----------------------编辑-------------------------- – 我只是将提供程序更改为Ec

  • 我有一个实体,它已经被持久化了,想把它添加到一个新生成的父实体(还没有持久化)。如果我尝试持久化父级,那么我会得到错误“Detached entity pass to persist:model.child”。我认为我必须以某种方式为孩子调用“EntityManager.merge()”,而不是“EntityManager.Persist()”。但我没有显式调用persist。这是由“Cascad