代码之家  ›  专栏  ›  技术社区  ›  Maurice

在JpaRepository上调用delete方法时未调用AspectJ方法

  •  0
  • Maurice  · 技术社区  · 6 年前

    我在一个叫做seedrecord的对象和一个叫做affiliatelink的对象之间有很多关系。为了删除附属链接,我需要首先从每个seedrecord的附属列表中删除对它的引用。之后,我使用spring Jparepository的delete方法删除对象。因为我的服务(AffiliateLinkService)中有不同的delete方法,所以我决定将这段代码放在AspectJ类中。但是,当调用deletemethod时,aspectJ方法在此之前不会被调用。有人能看看我的密码告诉我出了什么问题吗?

    @Before("execution(* org.springframework.data.jpa.repository.JpaRepository.delete(..))" +
            "&& within(Services.AffiliateLinkService) && args(entity)")
    private void deleteAffiliateLinkFromSeedRecordAffiliateLists(Object entity){
        log.info("hailing from SystemListenerService!");
        ((AffiliateLink)entity).getSeedRecords()
                .forEach(seedRecord -> {
                    seedRecord.getAffiliateLinks()
                            .remove(seedRecord);
                    seedRecordDao.save(seedRecord);
                });
    }
    

    编辑:问题不是由jparepository方法引起的。因为当我使用名为deleteMe()的包装器方法更改delete方法,并让aspect方法在此包装器方法之前运行时,它也不起作用。。

    @Before("execution(* Services.AffiliateLinkService.deleteMe(..))" +
            "&& args(entity)")
    

    另外,为了便于参考,我将aspect声明为bean,并将config类声明为 @EnableAspectJAutoProxy

    编辑2:当我在之前改变@时,事情变得更加奇怪 @Afterthrowing("execution(* *(..))") .

    然后在应用程序启动期间突然出现这个错误。

    说明:

    无法将bean“dataSourceInitializer”作为 'org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer' 因为它是一个JDK动态代理,实现: org.springframework.context.ApplicationListener网站

    行动:

    考虑将bean作为其接口之一注入,或者强制 通过设置PROXOTAL类= TRUE使用基于CGLIB的代理 @enablesync和/或@EnableCaching。

    问题是我哪儿也没有 dataSourceInitializer 显式声明,因此我不能用@Enable this或that注释它。。。上帝啊,我多么讨厌春天。

    注:我有另一个方法是在返回jparepository的save方法之后调用的,它起到了一种魅力,所以我不明白为什么delete建议不起作用。这是工作方法的注解。

    @返回后(“执行(*org.springframework.data.jpa.repository.JpaRepository.save(..)”+ “&!在(Services.SystemListenerService)&args(实体)“”内

    编辑3:这与我正在使用的参数AffiliateLink有关。例如,当我用long替换AffiliateLink参数时,before方法被调用,这就是AffiliateLink pojo。但我不认为pojo有什么不寻常的地方会导致这种情况:

    @Entity
    public class AffiliateLink implements Serializable {
        @Id
        @GeneratedValue(generator = "ID_GENERATOR")
        private Long id;
    
        @URL
        private String affiliateUrl;
    
        @URL
        private String affiliateImageUrl;
    
        private String title;
    
        private String description;
    
        private Double productValue;
    
        private boolean general;
    
        private byte rank;
    
        private boolean linkBroken;
    
        @Temporal(TemporalType.TIMESTAMP)
        @Column(updatable = false)
        @CreationTimestamp
        private Date creationDate;
    
    
        @ElementCollection @CollectionTable( name = "affiliate_keywords", joinColumns=@JoinColumn(name = "id", referencedColumnName = "id") ) @Column(name="keyword")
        private Set<String> keywords;
    
        @ManyToMany(mappedBy = "affiliateLinks")
        private Set<SeedRecord> seedRecords = new HashSet<>();
    
        @Enumerated(EnumType.STRING)
        private LocalizedStorefront localizedStorefront;
    
        private long seedId;
    
        private boolean plantClimbs;
    
        private boolean spicy;
    
        private boolean teaPlant;
    
        public AffiliateLink() { }
    
        public AffiliateLink(AffiliateLinkCreateDTO affiliateLinkCreateDTO) {
            this.title = affiliateLinkCreateDTO.getTitle();
            this.description = affiliateLinkCreateDTO.getDescription();
            this.general = affiliateLinkCreateDTO.isGeneral();
            this.rank = affiliateLinkCreateDTO.getRank();
            this.localizedStorefront = affiliateLinkCreateDTO.getLocalizedStorefront();
            this.productValue = affiliateLinkCreateDTO.getProductValue();
            this.keywords = affiliateLinkCreateDTO.getKeywords();
            this.seedId = affiliateLinkCreateDTO.getSeedId() != null ? affiliateLinkCreateDTO.getSeedId() : 0;
        }
    
        public AffiliateLink(String affiliateUrl,
                             String affiliateImageUrl,
                             String title,
                             String description,
                             Double productValue,
                             boolean general,
                             byte rank,
                             boolean linkBroken,
                             Set<String> keywords,
                             LocalizedStorefront localizedStorefront,
                             long seedId,
                             boolean plantClimbs,
                             boolean spicy,
                             boolean teaPlant) {
            this.affiliateUrl = affiliateUrl;
            this.affiliateImageUrl = affiliateImageUrl;
            this.title = title;
            this.description = description;
            this.productValue = productValue;
            this.general = general;
            this.rank = rank;
            this.linkBroken = linkBroken;
            this.keywords = keywords;
            this.localizedStorefront = localizedStorefront;
            this.seedId = seedId;
            this.plantClimbs = plantClimbs;
            this.spicy = spicy;
            this.teaPlant = teaPlant;
        }
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public Date getCreationDate() {
            return creationDate;
        }
    
        public void setCreationDate(Date creationDate) {
            this.creationDate = creationDate;
        }
    
        public boolean isPlantClimbs() {
            return plantClimbs;
        }
    
        public void setPlantClimbs(boolean plantClimbs) {
            this.plantClimbs = plantClimbs;
        }
    
        public boolean isSpicy() {
            return spicy;
        }
    
        public void setSpicy(boolean spicy) {
            this.spicy = spicy;
        }
    
        public boolean isTeaPlant() {
            return teaPlant;
        }
    
        public void setTeaPlant(boolean teaPlant) {
            this.teaPlant = teaPlant;
        }
    
        public long getSeedId() {
            return seedId;
        }
    
        public void setSeedId(long seedId) {
            this.seedId = seedId;
        }
    
        public Double getProductValue() {
            return productValue;
        }
    
        public void setProductValue(Double productValue) {
            this.productValue = productValue;
        }
    
        public String getAffiliateImageUrl() {
            return affiliateImageUrl;
        }
    
        public boolean isLinkBroken() {
            return linkBroken;
        }
    
        public void setLinkBroken(boolean linkBroken) {
            this.linkBroken = linkBroken;
        }
    
        public void setAffiliateImageUrl(String affiliateImageUrl) {
            this.affiliateImageUrl = affiliateImageUrl;
        }
    
        public String getAffiliateUrl() {
            return affiliateUrl;
        }
    
        public void setAffiliateUrl(String affiliateUrl) {
            this.affiliateUrl = affiliateUrl;
        }
    
        public String getTitle() {
            return title;
        }
    
        public Set<String> getKeywords() {
            return keywords;
        }
    
        public void setKeywords(Set<String> keywords) {
            this.keywords = keywords;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public boolean isGeneral() {
            return general;
        }
    
        public void setGeneral(boolean general) {
            this.general = general;
        }
    
        public byte getRank() {
            return rank;
        }
    
        public void setRank(byte rank) {
            this.rank = rank;
        }
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    
        public Set<SeedRecord> getSeedRecords() {
            return seedRecords;
        }
    
        public void setSeedRecords(Set<SeedRecord> seedRecords) {
            this.seedRecords = seedRecords;
        }
    
        public LocalizedStorefront getLocalizedStorefront() {
            return localizedStorefront;
        }
    
        public void setLocalizedStorefront(LocalizedStorefront localizedStorefront) {
            this.localizedStorefront = localizedStorefront;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            AffiliateLink that = (AffiliateLink) o;
            return general == that.general &&
                    rank == that.rank &&
                    Objects.equals(id, that.id) &&
                    Objects.equals(affiliateUrl, that.affiliateUrl) &&
                    Objects.equals(affiliateImageUrl, that.affiliateImageUrl) &&
                    Objects.equals(title, that.title) &&
                    Objects.equals(description, that.description) &&
                    Objects.equals(productValue, that.productValue) &&
                    localizedStorefront == that.localizedStorefront;
        }
    
        @Override
        public int hashCode() {
    
            return Objects.hash(id, affiliateUrl, affiliateImageUrl, title, description, productValue, general, rank, localizedStorefront);
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Maurice    6 年前

    我在春季论坛上的这篇文章解决了这个问题。 http://forum.spring.io/forum/spring-projects/aop/100146-aspect-advice-is-never-called

    方法应该是公共的而不是静态的,并在外部调用(这意味着该方法应该在另一个类中)。所以我将deleteMe方法移到了另一个类中并从那里调用它,现在@Before方面开始工作了。