我有2个表,第一个是父表,第二个是子表。
Table Employee:
Emp_Id, Name, Age, Salary, Travel_Allowance, Cost_To_Company
Table Allowance:
Id, Emp_Id, Type, Amount
每当在Allowance表中为Travel_Allowance类型记录插入/更新行时,我需要更新Employee表的Travel_Allowance列。
为此,我在Allowance表上写了一个触发器,只要在Travel_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)准备Allowance对象并将其添加到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不覆盖从Database触发器更新的值?
答案 0 :(得分:2)
好的,我认为你可以使用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
实例。
您可能已经有travelAllowance
的映射,因为您的表架构与Grails所期望的不匹配。也许是这样的?
static mapping = {
travelAllowance column: "Travel_Allowance"
}
如果是这样,只需在我的例子中进行更改。
将travelAllowance
更改为派生属性的副作用是Grails在执行架构创建/更新时不会为您生成该表列。就Grails而言,该专栏并不存在。要记住的事情。