Я искал подобный вопрос к этому, но безуспешно.
Моя цель: мне нужно получить имя пользователя того, кто создал определенную сущность, которое хранится в таблице аудита этой сущности на который ссылается Spring @ AuditTable.
Немного (надеюсь) объяснил: в этой конкретной ситуации я добавляю к ранее существующему запросу, созданному с помощью класса org.springframework.data.jpa.repository.JpaSpecificationExecutor, а также класс предиката (javax.persistence.criteria.Predicate). Соединения, как правило, производятся с именем класса (например, Join), из которого Spring получает имя таблицы. У меня вопрос, есть ли способ заставить Spring выглядеть по имени таблицы аудита вместо имени таблицы сущности?
Примером может быть:
@Entity @Table(name = "persons")
@Audited @AuditTable(name = "audit_persons")
public class Person {
private String id;
private String name;
private Job job;
/*getters and setters*/
}
@Entity @Table(name = "jobs")
@Audited @AuditTable(name = "audit_jobs")
public class Job {
private String id;
private String name;
/*getters and setters*/
}
public final class PersonSpecification {
private PersonSpecification(){}
public static Specification<Person> findBy(final String attributeName, final Object filterValue) {
return new Specification<Person>() {
@Override
public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.equal(root.get(attributeName), filterValue);
}
};
}
public static Specification<Person> findByJob(final Job job) {
return new Specification<Person>() {
@Override
public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Join<Person, Job> joinJob = root.join("job", JoinType.LEFT);
return cb.equal(joinJob.<Job>get("job"), job);
}
};
}
/*
public static Specification<Person> findByUsername(final String username) {
return new Specification<Person>() {
@Override
public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Join<Person, audit person?> join? = root.join(?, JoinType.LEFT);
return I don't know how to access;
}
};
}
*/
}
import static ().PersonSpecification.findBy;
import static ().PersonSpecification.findByJob;
@Service(value="personService")
public class PersonService {
@Autowired
private PersonDao personDao;
public List<Person> find(String id, String name, Job job /*, String username*/){
Specifications<Person> specifications = null;
if (!StringUtils.isBlank(id) && StringUtils.isNumeric(id)) {
specifications = loadFilter(specifications, findBy("id", id));
}else{
if (!StringUtils.isBlank(name)) {
specifications = loadFilter(specifications, findBy("name", name));
}
if (job != null) {
specifications = loadFilter(specifications, findByJob("job", job));
}
/*
if (!StringUtils.isBlank(username)) {
specifications = I don't know what to do here;
}
*/
}
return personDao.findAll(specifications);
}
}
Возможное решение: I думал о добавлении новой сущности, которая будет ссылаться на проверяемую сущность, например:
@Entity @Table(name = "audit_persons")
public class AuditedPerson {
private String id;
private Integer rev;
private Integer revtype;
private String username;
/*getters and setters*/
}
И тогда мой метод будет
public static Specification<Person> findByUsername(final String username) {
return new Specification<Person>() {
@Override
public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Join<Person, AuditedPerson> joinAudit = root.join(id, JoinType.LEFT);
return cb.and(cb.equal(joinAudit.get("username"), username),
cb.equal(joinAudit.get("revtype"), 0)); //this is so I get the creation instance's username
}
};
}
Я попытаюсь сделать эту работу , Уже есть способ сделать это? Должен ли я просто добавить собственный запрос, который делает это? Спасибо!