在Spring JPA

时间:2018-06-03 22:06:36

标签: java spring spring-boot reflection spring-aop

我想知道如何在保存到数据库之前获取对象的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 个答案:

答案 0 :(得分:1)

根据我的评论更新问题后,我会建议这样的事情:

助手类:

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]

答案 1 :(得分:0)

试试这个:

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);
}