代码之家  ›  专栏  ›  技术社区  ›  Aymen Kanzari

在spring jpa中保存对象之前触发

  •  1
  • Aymen Kanzari  · 技术社区  · 7 年前

    我想知道在被保存到数据库中并对其进行处理之前,如何获取对象的ID。我试图使用aop,我创建了一个方法 @Before 在执行spring数据保存方法之前执行特定处理的注释。

    下面的方法显示此错误:

    java.lang.NoSuchFieldException:ID

    @Before("execution(* com.next.commerce.back.repository.*.save(..)) && args(object)")
    public void before(JoinPoint joinPoint, Object object) {
        Field field = null;
        Class<? extends Object> clazz = object.getClass();
        try {
            field = clazz.getDeclaredField("id");
            field.setAccessible(true);
            field.set(object, getNextValue("Test"));
            logger.info("+++++++++++++++++++++++++++++++" + (Long) field.get(field));
        } catch (Exception e) {
            logger.error("Error", e);
        }
    }
    

    实体示例:

    @Document(collection = "address")
    public class Address extends Identity<Long> implements Serializable {
    
      private static final long serialVersionUID = 1L;
    
      private Integer zipCode;
    
      private String country;
    
    //getter and setter
    }
    
    public class Identity<ID extends Serializable> {
    
      @Id
      private ID id;
    
      public ID getId() {
        return id;
      }
    
      public void setId(ID id) {
        this.id = id;
      }
    
    }
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   kriegaex    7 年前

    根据我的评论,在你的问题更新后,我建议如下:

    帮助程序类:

    package de.scrum_master.app;
    
    import static java.lang.annotation.ElementType.FIELD;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;
    
    @Retention(RUNTIME)
    @Target(FIELD)
    public @interface Id {}
    
    package de.scrum_master.app;
    
    import static java.lang.annotation.ElementType.TYPE;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;
    
    @Retention(RUNTIME)
    @Target(TYPE)
    public @interface Document {
      String collection();
    }
    
    package de.scrum_master.app;
    
    import java.io.Serializable;
    
    public class Identity<ID extends Serializable> {
      @Id private ID id;
    
      public Identity(ID id) { this.id = id; }
      public ID getId() { return id; }
      public void setId(ID id) { this.id = id; }
      @Override public String toString() { return "Identity [id=" + id + "]"; }
    }
    
    package de.scrum_master.app;
    
    import java.io.Serializable;
    
    @Document(collection = "address")
    public class Address extends Identity<Long> implements Serializable {
      private static final long serialVersionUID = 1L;
    
      private Integer zipCode;
      private String country;
    
      public Address(Long id, Integer zipCode, String country) {
        super(id);
        this.zipCode = zipCode;
        this.country = country;
      }
    
      @Override
      public String toString() {
        return "Address [id=" + getId() + ", zipCode=" + zipCode + ", country=" + country + "]";
      }
    }
    

    驱动程序应用程序:

    package de.scrum_master.app;
    
    public class Application {
      public void save(Identity identity) {
        System.out.println("Saving " + identity);
      }
    
      public static void main(String[] args) {
        Application application = new Application();
        application.save(new Identity<Long>(1L));
        application.save(new Address(2L, 12345, "Germany"));
      }
    }
    

    方面:

    package de.scrum_master.aspect;
    
    import java.util.Random;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    
    import de.scrum_master.app.Identity;
    
    @Aspect
    public class IdSetterAspect {
      private static final Random RANDOM = new Random();
    
      @Before("execution(* de.scrum_master..save(..)) && args(identity)")
      public void beforeAdvice(JoinPoint thisJoinPoint, Identity identity) {
        System.out.println(thisJoinPoint);
        System.out.println("  Old ID = " + identity.getId());
        identity.setId(RANDOM.nextInt(1000));
        System.out.println("  New ID = " + identity.getId());
      }
    }
    

    控制台日志:

    execution(void de.scrum_master.app.Application.save(Identity))
      Old ID = 1
      New ID = 514
    Saving Identity [id=514]
    execution(void de.scrum_master.app.Application.save(Identity))
      Old ID = 2
      New ID = 995
    Saving Address [id=995, zipCode=12345, country=Germany]
    
        2
  •  0
  •   Ragnar    7 年前

    试试这个:

    try {
          Field field = Class.forName(object.getClass().getName()).getDeclaredField("id");
          field.setAccessible(true);
          logger.info("+++++++++++++++++++++++++++++++" + (Long) field.get(object));
    } catch (Exception e) {
          logger.error("Error", e);
    }