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

JPA PersistentObjectException:已分离的实体传递到Persister

苏坚成
2023-03-14

我在尝试使用Spring Data JPA和Hibernate作为JPA提供程序执行批插入操作时遇到了问题。

我有以下方法在我的服务。这就是抛出异常的地方。

    @Transactional
    private void saveAppointments() {

        // create StageFile reference object
        StageFile file = new StageFile();
        file.setFileName("3312_APPOINTMENT.API");
        file.setDeleteFlag('N');
        file.setInstitution(institution);

        for (StageAppointment appointment : appointments) {
            appointment.setStageFile(file);
            stageAppointmentRepository.save(appointment);
        }
    }

    @Transactional
    private void saveDepartments() {

        // create StageFile reference object
        StageFile file = new StageFile();
        file.setFileName("3312_DEPARTMENT.API");
        file.setDeleteFlag('N');
        file.setInstitution(institution);

        for (StageDepartment department : departments) {
            department.setStageFile(file);
            stageDepartmentRepository.save(department);
        }
    }

Institute是一个实例变量,并提前获取。

Institution institution = institutionRepository.findByActCode(3312);

我还将实体设置为级联、持久和合并。

@Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "stgAppointmentSeq")
    @SequenceGenerator(name = "stgAppointmentSeq", sequenceName = "T_STG_APPOINTMENT_SEQ", allocationSize = 50)
    @Column(name = "ID")
    private Long id;

    @ManyToOne(cascade = {CascadeType.PERSIST,CascadeType.MERGE}, fetch = FetchType.EAGER, optional = false)
    @JoinColumn(name = "FILE_ID", referencedColumnName = "ID")
    private StageFile stageFile;

    @ManyToOne(cascade = {CascadeType.PERSIST,CascadeType.MERGE}, fetch = FetchType.EAGER, optional = false)
    @JoinColumn(name = "STATUS_ID", referencedColumnName = "ID")
    private StageStatus stageStatus;
@Transactional
private void saveAppointments() {

    Institution institution = institutionRepository.findByActCode(3312);
    StageStatus stageStatus = stageStatusRepository.findOne(1L);

    // create StageFile reference object
    StageFile file = new StageFile();
    file.setFileName("3312_APPOINTMENT.API");
    file.setDeleteFlag('N');
    file.setInstitution(institution);

    for (StageAppointment appointment : appointments) {
        appointment.setStageFile(file);
        appointment.setStageStatus(stageStatus);
        stageAppointmentRepository.save(appointment);
    }
}

为什么这段代码起作用

    @Transactional
    private void saveUsingTransaction() {

        Institution institution = institutionRepository.findByActCode(3312);
        StageStatus status = stageStatusRepository.findOne(1L);

        StageFile file =  new StageFile();
        file.setDeleteFlag('N');
        file.setFileName("3312_DIRECTORY.API");
        file.setInstitution(institution);

        StageDirectory directory = new StageDirectory();
        directory.setLocalId("11111111111111111");
        directory.setFirstName("Joe");
        directory.setLastName("Joe");
        directory.setPrimaryEmail("joe@gmail.com");
        directory.setStageFile(file);
        directory.setStageStatus(status);

        stageDirectoryRepository.save(directory);
    }

而此代码不

@Transactional
private void savePassingDirectory(StageDirectory directory) {

    Institution institution = institutionRepository.findByActCode(3312);
    StageStatus stageStatus = stageStatusRepository.findOne(1L);

    // create StageFile reference object
    StageFile file = new StageFile();
    file.setFileName("3312_DIRECTORY.API");
    file.setInstitution(institution);
    file.setDeleteFlag('N');

    directory.setStageFile(file);
    directory.setStageStatus(stageStatus);
    stageDirectoryRepository.save(directory);
}

共有1个答案

桓信鸥
2023-03-14

@transactional仅适用于从外部对象到托管bean的方法调用。

类内方法调用(根据定义,私有方法只能以这种方式调用)不会被容器拦截,因此对于这些,注释@transactional不起作用。所以我认为你需要检查一下你的交易边界到底在哪里。

我的猜测是saveoplements当前运行在任何事务之外。您的InstitutionRepository.findByactCode()可能是对托管bean的正确调用,因此它使用事务。当该方法再次返回时,在调用StageAppointmentRepository.save()时,在任何事务之外执行操作,以最终输入新事务。

首先,您必须确保saveoplements方法本身实际在事务中运行(例如,使其public并从您@inject的任何地方直接调用它),然后您必须确保后续的方法调用重用该事务,而不是启动新的事务(即,不具有@transactionattribute(TransactionAttributeType.requires_new))

 类似资料:
  • 我在stackoverflow上读了很多关于相同异常的文章,但没有找到任何实际帮助我的东西,所以我在这里:

  • 另外,我有一个IOC托管bean,它内部有一个事务方法。 有2个实体具有单向Many2One-- AuModule在上没有引用

  • 我得到了“分离的实体传递到持久”,但我不明白,该对象如何能够处于分离状态。 这里首先是一些上下文。 每个用户和角色有两个: 实体--除了名称之外--有几个不应与此问题相关的字段,外字段角色来自其基类: 在应用程序启动时,我希望确保此ApplicationRunner中存在管理员用户: 应用程序在启动时抛出异常并关闭: 我在这里的理解是,在从存储库中检索到之后就处于分离状态。 为何超脱?我假设方法上

  • 我有一段很长的JPA+Hibernate代码,它试图在循环中将大量记录插入到DB中。 更奇怪的是,我可以用下面的代码在一次迭代中再现错误。“分离的实体...”第二次刷新时抛出错误。那么这是否意味着第一次同花顺是一个无操作?

  • 我有两个模型,一个用于存储用户详细信息,使用该Id,我试图将用户位置保存在另一个表中,该表使用用户的相同Id作为主键。 为什么我会出现这个错误?坚持是什么意思?我正在使用MySQL数据库(&I)

  • 当试图在web应用程序上创建课程实体实例时,我们遇到以下错误。这是一个JHipster应用程序完整的错误日志,下面是,但主要错误是 更新的代码: