如何使用 @ManyToMany 审核 @JoinTable

Posted

技术标签:

【中文标题】如何使用 @ManyToMany 审核 @JoinTable【英文标题】:How to audit a @JoinTable with @ManyToMany 【发布时间】:2021-01-30 16:40:22 【问题描述】:

我正在开发一个带有 H2 数据库的 Spring-Boot 项目。我有两个实体PortfolioReport,两者之间存在多对多关联。 我希望对这些实体进行审计,因此我按照this tutorial 通过带有自定义字段的AuditorAware 接口进行审计。

这两个实体都经过了很好的审计,列是在数据库中创建的。但是,连接表portfolio_reports 未经过审计。我如何也审计连接表?

Portfolio.java

@Entity
@Table(name = "portfolio")
public class Portfolio extends Auditable<String> implements Serializable 

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    @Unique
    private String name;

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    @JoinTable(name = "portfolio_report", joinColumns = @JoinColumn(name = "portfolio_id"), inverseJoinColumns = @JoinColumn(name = "report_id"))
    private List<Report> reports;
    
    // Getters and setters

Report.java

@Entity
@Table(name = "report")
public class Report extends Auditable<String> implements Serializable 

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "axioma_id")
    private Long axiomaId;

    @Column(name = "name")
    private String name;

    @AuditJoinTable
    @ManyToMany(mappedBy = "reports", cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    private List<Portfolio> portfolios;

    // Getters and setters

Auditable.java

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class Auditable<U> 

    @Version
    @Column(name = "version_no")
    protected Long versionNo;

    @CreatedDate
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created_date")
    protected Date createdDate;

    @LastModifiedDate
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "modified_date")
    protected Date modifiedDate;


AuditorAwareImpl.java

public class AuditorAwareImpl implements AuditorAware<String> 

    @Override
    public Optional<String> getCurrentAuditor() 
        return Optional.of("Admin");
    

PersistenceConfiguration.java

@Configuration
@EnableJpaAuditing(auditorAwareRef = "auditorAware")
public class PersistenceConfiguration 

    @Bean
    public AuditorAware<String> auditorAware() 
        return new AuditorAwareImpl();
    

【问题讨论】:

【参考方案1】:

问题:

很明显,Auditable 应该在中间表中添加一些列,以维护PortfolioReport 之间的关系,并且该表是在后台创建的,您无法在程序中访问该表。只有 hibernate 可以使用该表来维护实体之间的关系并进行连接操作。

解决方案:

在这里,您应该创建保持PortfolioReport 之间的多对多关系的联接表,这样您就可以在程序中拥有像PortfolioReport 这样的实体,该实体可以从Auditable 扩展。请阅读以下帖子以了解如何执行此操作:The best way to map a many-to-many association with extra columns when using JPA and Hibernate

【讨论】:

我知道该解决方案,但发现它不必要地复杂,并且不喜欢我的多对多关系转换为双向一对多关系。没有别的办法吗?

以上是关于如何使用 @ManyToMany 审核 @JoinTable的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 select_related 获取 ManyToMany 字段值

如何使用 JPQL 删除 ManyToMany 项目?

Django:如何从 ManyToMany 迁移到 ForeignKey?

如何使用 Django Rest Framework 向 ManyToMany 字段添加数据?

如何在模板上显示 Django ManyToMany?需要简单的代码

如何在 ModelAdmin.formfield_for_manytomany() 中使用 Django QuerySet.union()?