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