【问题标题】:Audit Logging skips logging ID of tables with composite-primary key审计日志跳过具有复合主键的表的日志记录 ID
【发布时间】:2017-03-07 22:28:32
【问题描述】:

我正在实施Audit Logging 1.1 Grails Plugin 以在我们的项目实施过程中跟踪我的域类的更改。这些是我们场景的示例域对象:

学生需要回答问题。一个问题可以要求一个或多个答案。
class Question {
    static auditable = true

    Integer id
    String content

    static hasMany = [
        answers: Answer
    ]
}

class Student {
    static auditable = true

    Integer id
    String name

    static hasMany = [
        answers: Answer
    ]
}

class Answer implements Serializable {
    static auditable = true

    Integer sequence
    String value

    static belongsTo = [
        student: Student,
        question: Question
    ]

    static mapping = {
        id composite: ["student", "question", "sequence"]
    }
}

每次我对这些表中的任何一个执行插入/更新时,插件都会触发一个事件并将其记录到我的 AuditLog 表中。除Answer 表外,所有DML 均按预期成功记录。问题是PERSISTED_OBJECT_ID 始终为空:

+----+---+------------+------------+---------------------+---------------+-----------+-----------+
| ID | … | CLASS_NAME | EVENT_NAME | PERSISTED_OBJECT_ID | PROPERTY_NAME | OLD_VALUE | NEW_VALUE |
+----+---+------------+------------+---------------------+---------------+-----------+-----------+
| …  | … | Answer     | UPDATE     |                     | value         | A         | B         |
| …  | … | Answer     | UPDATE     |                     | value         | B         | A         |
+----+---+------------+------------+---------------------+---------------+-----------+-----------+

我尝试包含logIds = true 配置,但它仍然没有持续存在。如果没有该列,我无法确定哪个Answer 是由谁更新的。我希望这将是我拥有的所有复合主键域类的情况。

我能做些什么来解决这个问题?

【问题讨论】:

    标签: grails audit-trail


    【解决方案1】:

    当我的 new/oldValue 是域类对象时,我在 2.x 插件版本中遇到了同样的问题。我通过覆盖保存为值的域的 toString() 方法来决定它。尝试为您的“学生”和“问题”域覆盖 toString()。

    更新:

    我没有在我的项目中使用复合键作为 Id(这似乎是你的 persistedObjectId 为空的原因),而且我使用了 2.x 版本的插件。我对看起来像您的问题的决定可能会对您有所帮助: 我有域名:

    class Manager {
    }
    
    class Customer {
    }
    
    class Item {
    Manager manager
    Customer customer
    Item parentItem
    BigDecimal qtyOnHand
    }
    

    我记录了 qtyOnHand 和 parentItem 的变化。首先,一切都很容易。第二个(我记得默认值是这样的:“[id:15]Object123402”): 1.覆盖toString()

     public String toString() {
        id 
    }
    

    2。在配置中:logIds = false => 插件只写入对象的 id

    我还使用“uri”记录 managerId 和 customerId(为了简单起见):

    def getAuditLogUri = {
        managerId as String
    }
    

    我们可以在 uri 中写入所有内容,而不是在 beforeInsert 中写入过去:

    class Item {
    ......
    def getAuditLogUri = {
        getAuditFields()
    }
    
    private Map getAuditFields() {
        return [managerId: manager.id, customerId: customer.id]
    }
    ....
    }
    
    class AuditLog{
    String actor
    String uri
    String className
    String persistedObjectId
    String propertyName
    String oldValue
    String newValue
    String managerId
    String customerId
    .....
    def beforeInsert() {
        getAdditionalFields(uri)
    }
    private void getAdditionalFields(String fields) {
        Map map = Eval.me(fields)
        managerId = map.managerId
        customerId = map.customerId
    }
    

    在我的项目中一切正常,我认为它对于persistedObjectId-field 也一样

    【讨论】:

    • 那我该怎么return呢?
    猜你喜欢
    • 1970-01-01
    • 2018-12-08
    • 2017-06-26
    • 2011-01-30
    • 2016-03-23
    • 2011-03-18
    • 2011-02-02
    • 2016-08-02
    • 1970-01-01
    相关资源
    最近更新 更多