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

持久化分离实体时,Spring数据JPA审核失败

鞠嘉誉
2023-03-14

我已经使用Spring Data JPA AuditingEntityListener和AuditorAware bean设置了JPA审计。我想要的是即使在具有预定义标识符的实体上也能够持久化审计师详细信息。问题是,当具有预定义id的JPA实体被持久化和刷新时,它的审计师详细信息无法持久化:

对象引用未保存的临时实例-在刷新之前保存临时实例:me。审计道。审计详情

有趣的是,当保存具有生成id的实体时,一切都很好。在这两种情况下,实体都是新的。我无法通过hibernate代码找出问题所在,因此我创建了一个示例项目来演示这一点(测试类me.auditing.dao.AuditedEntityIntegrationTest),它具有预定义和生成标识符的实体,应该进行审计。

这些实体是:

@Entity
public class AuditedEntityWithPredefinedId extends AuditableEntity {

    @Id
    private String id;

    public String getId() {
        return id;
    }

    public AuditedEntityWithPredefinedId setId(String id) {
        this.id = id;
        return this;
    }
}

和:

@Entity
public class AuditedEntityWithGeneratedId extends AuditableEntity {

    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid")
    private String id;

    public String getId() {
        return id;
    }

    public AuditedEntityWithGeneratedId setId(String id) {
        this.id = id;
        return this;
    }
}

其中父类是:

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AuditableEntity implements Serializable {

    private static final long serialVersionUID = -7541732975935355789L;

    @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
    @CreatedBy
    private AuditorDetails createdBy;

    @CreatedDate
    private LocalDateTime createdDate;

    @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
    @LastModifiedBy
    private AuditorDetails modifiedBy;

    @LastModifiedDate
    private LocalDateTime modifiedDate;

审计员getter实现是:

@Override
public AuditorDetails getCurrentAuditor() {
    return new AuditorDetails()
            .setId(null)
            .setUserId("someUserId")
            .setDivisionId("someDivisionId");
}

编辑2016-08-08:似乎当保存一个具有预定义id的新实体时,它会得到两个不同的实例createdBy和modifiedBy AuditorDetails,如果实体实际上不是新的,这是非常合乎逻辑的。因此,一个生成了的全新实体将获取同一实例的两个AuditorDetails,而手动设置id的实体则不会。我通过在AuditorAware bean中保存审核员详细信息,然后将其返回给AuditingHandler来测试它。

共有1个答案

尹欣怿
2023-03-14

好的,所以目前我能找到的唯一解决方案是在将AuditorDetails写入已审计实体之前,实际保留它,如下所示:

@Override
@Transactional
public AuditorDetails getCurrentAuditor() {
    AuditorDetails details = new AuditorDetails()
            .setId(null)
            .setUserId("someUserId")
            .setDivisionId("someDivisionId");
    return auditorDetailsRepository.save(details);
}

这并不是最优雅的解决方案,但目前它仍然有效。

 类似资料:
  • 我正在使用springboot jpa存储库保存方法 这是完整的错误:2020-06-09 15:49:02.371[nio-8080-exec-4]。M.M.A.ExceptionHandlerExceptionResolver:由处理程序执行导致的解析异常:org.springframework.dao.invalidDataAccessapiusageException:传递给persist

  • 我正在尝试使用JPA合并具有@OneTo多人关系的实体,但它会抛出设置为持久化错误的分离实体。我没有持久化实体,我正在合并它。我只是在使用连接获取将Alumno实体加载到他的Matcourse a实体时遇到问题。以下是代码: 注:Alumno指学生,Asignatura指学科,Matricula指学生学科,是一名学生与其学科之间的关系。这种关系有很多种,都有额外的桌子。 更详细的信息:使用下一个查

  • 我在提交表单时遇到以下错误: org.hibernate.PersistentObjectException:传递给Persisted的分离实体:com.project.pmet.model.Account;嵌套异常为javax.persistence.persistenceException:org.hibernate.persistentObjectException:传递到persist的分

  • 我正在尝试持久化一个与其他已经持久化的对象具有多对多关系的对象。 下面是我的持久化对象(它们已经在db中持久化了,这是一个MySql):- 产品 这是我的no persisted对象,我正在尝试创建它 这是我的类,它接收产品名称的数组,使用该名称查看产品并将其放入reservation对象。 下面是我的接口: 严重:路径为[/web]的上下文中servlet[dispatcher]的servlet

  • 我有一个问题,分离实体传递到持久性。我以为我知道什么是超然的实体,但显然这对我来说太多了...因此,无论如何,我试图创建一个Person对象,该对象具有一个Interviewer对象,而Interviewer对象具有一个Office对象,每次尝试持久化Person时,我都会得到异常(在本例中,Office是分离的实体)。相关代码如下所示: 是帮助器类的静态方法: 您可能会注意到创建面试官的help

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