sql-server - Grails域更新与数据库触发器更新

标签 sql-server grails gorm

我有2个表,第一个是父表,第二个是子表。

Table Employee:
Emp_Id, Name, Age, Salary, Travel_Allowance, Cost_To_Company

Table Allowance:
Id, Emp_Id, Type, Amount

在这里,每当为津贴表中的Travel_Allowance类型记录插入/更新一行时,我都需要更新Employee表的Travel_Allowance列。

为此,每当对Travel_Allowance类型记录执行插入/更新操作时,我就在Allowance表上编写了一个触发器以更新Employee表Travel_Allowance列。

触发:
CREATE TRIGGER [trig_updateEmployeeOnAllowanceUpsert]
ON [Allowance]
FOR INSERT,UPDATE
AS

UPDATE Employee SET Travel_Allowance = i.amount
FROM Employee e 
INNER JOIN INSERTED i ON e.emp_id = i.emp_id
AND i.type = 'TravelAllowance';

在Grails中,我的代码如下:
class Employee {
    String name
    Integer age
    BigDecimal salary
    BigDecimal travelAllowance
    BigDecimal costToCompany
    static hasMany = [allowances: Allowance]
}

class Allowance {
    Employee employee
    BigDecimal amount

    static belongsTo = [employee: Employee]
}

A)准备津贴对象并将其添加到Employee对象中,例如-
def updateAllowances(def employeeId, def allowanceAmount) {
    Employee emp = Employee.get(employeeId)
    Allowance a = new Allowance()
    a.employee = emp
    a.amount = allowanceAmount
    emp.addToAllowances(a)

    // Calculate Cost To Company
    def newCost = 0
    emp.alowances.each { allowance ->
        newCost += allowance.amount
    }
    emp.costToCompany = newCost + emp.salary;
    emp.save(flush:true, failOnError: true)
}

上面的代码在更新现有Travel_Allowance类型记录时工作正常。但是,在添加新的Travel_Allowance类型记录时,这无法按预期方式工作。

在添加新的Travel_Allowance类型记录时,触发器将使用新的Allowance记录量更新Employee表。然后Grails用Travel_allowance列中的先前值覆盖相同的记录。

如何使Grails不覆盖从数据库触发器更新的值?

最佳答案

好的,我认为您可以使用Grails派生的属性来解决此问题。派生属性基本上是SQL计算字段。因此,您可以做的是使travelAllowance成为派生属性,该属性仅返回Travel_Allowance SQL列:

class Employee {
    String name
    Integer age
    BigDecimal salary
    BigDecimal travelAllowance
    BigDecimal costToCompany
    static hasMany = [allowances: Allowance]

    static mapping = {
        travelAllowance formula: 'Travel_Allowance'
    }
}

这将告诉GORM / Hibernate将Employee.travelAllowance设为只读,这意味着它不会持久保存对属性的更改。相反,它将始终仅从表中读取值,因此,当您保存Employee实例时,它将不会覆盖该值。这意味着触发器将完全负责保持该值。通过Allowance实例。

您的表模式与Grails期望的不匹配,您可能已经为travelAllowance映射了。也许是这样的吗?
static mapping = {
    travelAllowance column: "Travel_Allowance"
}

如果是这样,只需像我的示例一样更改它。

警告

travelAllowance更改为派生属性的副作用是,在进行模式创建/更新时,Grails不会为您生成该表列。就Grails而言,该列不存在。要记住的事情。

关于sql-server - Grails域更新与数据库触发器更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37235154/

相关文章:

Grails + Tomcat6 + 多个实例 + 共享库文件夹

caching - 有没有一种grails方式来缓存带有超时的grails域对象

grails - 亲子偷懒获得 child 的身份证

grails - 查找时跳过锁定的GORM对象

sql-server - 为什么将文本转换为 varchar 而不指定长度会在 30 个字符处截断文本?

sql-server - 更改 SQL 表中的性别值

grails - 无法在 Grails 3.1.1 中安装 HTML5 拖放多文件上传插件

grails - 不需要的GORM表创建

c# - 请求失败,HTTP 状态为 401 : Unauthorized IN SSRS

sql - 如何使用下一行和上一行选择两个日期之间的行