java - 有没有办法引用规格(春季)的审计表?
问题描述
我一直在寻找与此类似的问题,但没有成功。
我的目标:我需要获取创建某个实体的用户名,该用户名存储在通过 Spring 的 @AuditTable 引用的所述实体的审计表中。
有点(希望)解释:在这种特殊情况下,我将添加到使用 org.springframework.data.jpa.repository.JpaSpecificationExecutor 类以及 Predicate 类(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);
}
}
一个可能的解决方案:我正在考虑添加一个引用被审计实体的新实体,如下所示:
@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
}
};
}
我会努力完成这项工作。有没有办法做到这一点?我应该只添加一个执行此操作的本机查询吗?谢谢!
解决方案
One solution would be to use JPA @SecondaryTable
with a database view.
Firstly, create a view (say vw_person_additional_data) from the audit table that selects only the initial 'created' record for each Person.
Update your person Entity as below. The @SecondaryTable
annotation lets us map an Entity to one or more tables or views.
@Entity
@Table(name = "persons")
@Audited
@AuditTable(name = "audit_persons")
//secondary table referencing our new view
@SecondaryTable(name = "vw_person_additional_data",
pkJoinColumns = {@PrimaryKeyJoinColumn(name = "person_id",
referencedColumnName = "id")})
public class Person {
private String id;
private String name;
private Job job;
@Column(name = "username", table="vw_person_additional_data") //column in view
private String createdBy;
}
The createdBy
property is now just like any other property of Person
when it comes to writing specifications.
推荐阅读
- angular - MVC Web 应用程序分阶段转换为 Angular
- c# - 如何使用特殊对象列表作为从 C# 中的同一类继承的类型的实例?
- css - 如何在 Angular Material Design 中为嵌套元素添加 CSS
- r - Ggplot2 计算时间段
- python - 如何使用 Python 执行终端命令
- python - Pinecsript 到 Python 的转换
- r - 如何将月份和日期没有前导零的字符转换为日期?
- python - 使用 Python 从 BAM 文件和 vcf 文件中提取具有不同位置的读取和配对(PYSAM 和 PYSAM,也可以使用 bamnostics)
- c - C递归函数不可能?
- java - 如何将动作侦听器添加到静态 Jbutton?