hibernate - Grails GORM 使用不可变的嵌入对象

原文 标签 hibernate grails groovy grails-orm grails-2.0

我有一个 GORM 类,它在其中使用了一个嵌入式实例。嵌入的实例是一个不可变的类。当我尝试启动应用程序时,它抛出了未找到 setter 属性的异常。

Caused by: org.hibernate.PropertyNotFoundException: Could not find a setter for property amount in class com.xxx.Money.

这是我的 GORM 类(class):
class Billing {
    static embedded = ['amount']
    Money amount
}

并且 Money 被定义为不可变的:
final class Money {
    final Currency currency
    final BigDecimal value

    Money(Currency currency, BigDecimal value) {
        this.currency = currency
        this.value = value
    }
}

无论如何要在不使 Money 可变的情况下解决这个问题?

谢谢!

最佳答案

Grails 和 hibernate 通常需要完整的域类是可变的,以支持 hibernate 提供的所有功能。

您可以使用多列 hibernate UserType 存储 Money 金额,而不是嵌入 Money 域类。以下是如何编写 UserType 的示例:

import java.sql.*
import org.hibernate.usertype.UserType

class MoneyUserType implements UserType {

    int[] sqlTypes() {
        [Types.VARCHAR, Types.DECIMAL] as int[]
    }

    Class returnedClass() {
        Money
    }

    def nullSafeGet(ResultSet resultSet, String[] names, Object owner)  HibernateException, SQLException {
        String currency = resultSet.getString(names[0])
        BigDecimal value = resultSet.getBigDecimal(names[1])
        if (currency != null && value != null) {
            new Money(currency, value)
        } else {
            new Money("", 0.0)
        }
    }

    void nullSafeSet(PreparedStatement statement, Object money, int index) {
        statement.setString(index, money?.currency ?: "")
        statement.setBigDecimal(index+1, money?.value ?: 0.0)
    }

    ...

}

要在域类中使用它,请将字段映射到 UserType 而不是嵌入它:
class Billing {
    static mapping = {
        amount type: MoneyUserType
    }
    Money amount
}

关于hibernate - Grails GORM 使用不可变的嵌入对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20806095/

相关文章:

java - 使用 hibernate 搜索自动完成

java - JUnit 测试之间的相同 hibernate session 导致问题

grails - 登录事件监听器中的另一个事务错误更新或删除了行?

grails - 是什么触发Grails基于HTTP状态的异常映射?

string - 将实体中的列表转换为数据库中的单个字符串列

java - hibernate 中的OneToMany关系创建4个表

grails - 在插件中使用主应用程序中的域类

java - 如何从 Groovy 注入(inject)我的 Controller 层

groovy - 如何在 groovy 脚本中运行 ODI 映射?

java - gradle:封装自定义dsl的最佳方法