Триггер перед сохранением объекта в Spring JPA - PullRequest
0 голосов
/ 04 июня 2018

Мне интересно, как я могу получить идентификатор объекта перед сохранением в БД и обработать его.Я попытался использовать AOP, я создал метод с аннотацией @Before, который выполняет определенную обработку перед выполнением метода сохранения данных пружины.

Приведенный ниже метод отображает эту ошибку:

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 голосов
/ 05 июня 2018

После обновления вашего вопроса в ответ на мой комментарий я бы предложил что-то вроде этого:

Вспомогательные классы:

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]
0 голосов
/ 04 июня 2018

попробуйте это:

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