Grails 的 hasMany 是独一无二的

2023-12-24

这个问题是我提出的问题的扩展/组合here https://stackoverflow.com/questions/18295781/account-for-hasmany-relationships-in-equals-and-hashcode and here https://stackoverflow.com/questions/18285202/validate-instance-of-domain-class-is-unique.

我的最终目标是拥有以下领域的类:

  1. The equals and hashCode生成的方法@EqualsAndHashCode take hasMany考虑到属性
  2. The unique域类中属性的约束采用hasMany考虑到属性
  3. 域类的实例只要其属性之一使其不同于已存在的实例,就被认为是唯一的。

感谢@James Kleeh 和@dmahapatro,我想我已经很接近了,但是第2 点和第3 点给我带来了麻烦。

我第一次尝试测试我的需求是单元测试testFooWithMockedBar in my FooTests.groovy文件。我正在尝试使用Bar.get()在那次测试中,但它不起作用。我不认为打电话给mockForConstraintsTests要么工作。

我很确定我在下一次测试中纠正了这个问题,testFooWithoutMockedBar,但我不确定测试是否按照我的想法进行,我将在接下来解释。

通过后testFooWithoutMockedBar我尝试在开发模式下运行该应用程序,看看它是否按预期工作。不幸的是bars行中的属性prop1(unique: ['prop2', 'prop3', 'bars'])在文件中Foo.groovy正在阻止 Grails 创建foo数据库中的表。这是我得到的错误:

| Error 2013-08-20 16:17:52,249 [localhost-startStop-1] ERROR hbm2ddl.SchemaExport  - Unsuccessful: create table foo (id bigint not null auto_increment, version bigint not null, prop1 varchar(255) not null, prop2 varchar(255) not null, prop3 varchar(255) not null, primary key (id), unique (foo_bars_id, prop3, prop2, prop1)) ENGINE=InnoDB
| Error 2013-08-20 16:17:52,250 [localhost-startStop-1] ERROR hbm2ddl.SchemaExport  - Key column 'foo_bars_id' doesn't exist in table
| Error 2013-08-20 16:17:52,309 [localhost-startStop-1] ERROR hbm2ddl.SchemaExport  - Unsuccessful: alter table foo_bar add index FKD76E651A96EEE146 (foo_bars_id), add constraint FKD76E651A96EEE146 foreign key (foo_bars_id) references foo (id)
| Error 2013-08-20 16:17:52,310 [localhost-startStop-1] ERROR hbm2ddl.SchemaExport  - Can't create table 'foobar.#sql-474_8c' (errno: 150)

我不确定是否有一个绝妙的方法来解决这个问题。我能想到的解决这个问题的唯一方法是使用自定义验证器Foo.groovy:

class Foo {

...

    boolean isUnique
    static transients = ['isUnique']

    static constraints = {
        isUnique(
            validator: { val, obj ->
                def rslt = true
                for(foo in Foo.getAll()) {
                    if (foo == obj) {
                        rslt = false
                        break
                    }
                }
                return rslt
            }
        )
        bars(nullable: false)
    }

有更好的方法来做我想做的事吗?

Foo.groovy

package foobar

@groovy.transform.EqualsAndHashCode
class Foo {

    String prop1
    String prop2
    String prop3

    Set<Bar> bars
    static hasMany = [bars: Bar]

    static constraints = {
        prop1(unique: ['prop2', 'prop3', 'bars']) // The 'bars' in this line is preventing Grails from creating the foo table in the database.
        bars(nullable: false)
    }
}

格罗维

package foobar

@groovy.transform.EqualsAndHashCode
class Bar {
    String prop1
}

FooTests.groovy

package foobar

import grails.test.mixin.*
import org.junit.*

@TestFor(Foo)
@Mock(Bar)
class FooTests {

    void testFooWithMockedBar() {

        // Create existing instances to validate against
        mockForConstraintsTests(Bar, [
                new Bar(prop1: "a"),
                new Bar(prop1: "b"),
                new Bar(prop1: "c"),
                new Bar(prop1: "d")
            ]
        )
        mockForConstraintsTests(Foo, [
                new Foo(prop1: "a", prop2: "b", prop3: "c", bars: [Bar.get(1), Bar.get(2)])
            ]
        )

        // Validation should fail if all properties are null
        def foo = new Foo()
        assert !foo.validate()
        assert "nullable" == foo.errors["prop1"]
        assert "nullable" == foo.errors["prop2"]
        assert "nullable" == foo.errors["prop3"]
        assert "nullable" == foo.errors["bars"]

        // Test unique constraints
        foo = new Foo(prop1: "a", prop2: "b", prop3: "c", bars: [Bar.get(1), Bar.get(2)])

        assert !foo.validate()
        assert "unique" == foo.errors["prop1"]

        // Validation should pass with all unique, not null properties
        foo = new Foo(prop1: "a", prop2: "b", prop3: "c", bars: [Bar.get(3), Bar.get(4)])
        assert foo.validate()

        // Test equals and hashCode
        assert foo == new Foo(prop1: "a", prop2: "b", prop3: "c", bars: [Bar.get(3), Bar.get(4)])
    }

    void testFooWithoutMockedBar() {

        // Create existing instances to validate against
        def bars1 = [new Bar(prop1: "a"), new Bar(prop1: "b")]
        def bars2 = [new Bar(prop1: "c"), new Bar(prop1: "d")]
        mockForConstraintsTests(Foo, [
                new Foo(prop1: "a", prop2: "b", prop3: "c", bars: bars1)
            ]
        )

        // Validation should fail if all properties are null
        def foo = new Foo()
        assert !foo.validate()
        assert "nullable" == foo.errors["prop1"]
        assert "nullable" == foo.errors["prop2"]
        assert "nullable" == foo.errors["prop3"]
        assert "nullable" == foo.errors["bars"]

        // Test unique constraints
        foo = new Foo(prop1: "a", prop2: "b", prop3: "c", bars: bars1)

        assert !foo.validate()
        assert "unique" == foo.errors["prop1"]

        // Validation should pass
        foo = new Foo(prop1: "a", prop2: "b", prop3: "c", bars: bars2)
        assert foo.validate()

        // Test equals and hashCode
        assert foo != new Foo(prop1: "a", prop2: "b", prop3: "c", bars: bars1)
        assert foo == new Foo(prop1: "a", prop2: "b", prop3: "c", bars: bars2)
    }
}

try

@EqualsAndHashCode(includeFields=true)

or

@EqualsAndHashCode(callSuper=true)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Grails 的 hasMany 是独一无二的 的相关文章

  • Tomcat 上的 Grails - 如何记录原始 HTTP 请求/响应

    我找不到配置我的虚拟教程 Grails 应用程序来记录 Grails 服务器 实际上是 Tomcat 接受 生成的所有 HTTP 请求和响应的方法 这可能吗 另一种选择是使用 tomcat 的内置访问日志记录 http tomcat apa
  • 向grails中的所有视图添加变量

    我试图在所有视图中为当前用户 POJO 设置一个变量 以便我可以获得用户名之类的信息并检查他们在每个视图 包括默认布局 上的角色 如何在 grails 中设置某些内容 例如 currentUser 以便在每个 grails 视图中都可以访问
  • 执行 grails/groovy 时,Linux 上没有可用的控制台输出

    当执行 groovy 脚本或 grails 应用程序时 没有可用的输出 输入 gt 只有一个清晰的控制台屏幕 即使不启动 X Window System 输出也是不可见的 我也尝试过 grailscompile plain output 也
  • Grails:如何更改默认视图位置?

    我有控制器AdminTagController 默认情况下视图将位于 adminTag文件夹 是否可以将此控制器的默认文件夹更改为 admin view 我可以为每个方法指定视图 但这并不酷 谢谢 可以用以下命令更改它拦截器后 http g
  • 如何处理“IllegalStateException:BeanFactory 未初始化或已关闭”?

    使用 Tomcat 7 上的 Grails 2 0 0 我在启动时得到以下结果 2011 08 21 11 10 09 758 main ERROR StackTrace Full Stack Trace java lang Illegal
  • Grails Log4J 未登录生产环境

    我有一个 Grails 1 3 7 应用程序 并尝试在配置中设置 log4j 以用于生产 log4j 设置在开发中很好 但我无法在生产中显示任何内容 我正在尝试制作一个滚动文件等 但我无法显示任何内容 我什至在 信息 级别进行了配置 这样我
  • 从 Glassfish 取消部署 Grails 应用程序会发生类不变性违规

    我有一个在 Glassfish 中运行的 Grails 应用程序 但是当我取消部署时 它会出现 违反类不变性 快速查看堆栈跟踪并在网络上搜索报告 这是 Log4j 的问题 我当时使用的是最新的log4jlog4j 1 2 16 jar 任何
  • 空白约束和空约束之间的区别

    空白约束和空约束有什么区别 我有以下课程 class Task String title String notes TekUser assignedTo Date dueDate TekEvent event static constrai
  • 转换 Java -> Grails ... 如何加载这些属性?

    我正在将 Java Web 应用程序转换为 Grails 1 2 1 在我的 Java 应用程序中 我有一个从 properties 文件加载属性的单例 我已经看到我可以将其加载到 Config groovy conf 文件中 如果我的属性
  • Spring IO 这个名字是什么意思? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 2013 年秋季 Spring 推出了新网站 spring io http spring io 并宣布了其新平台 弹簧IO http sp
  • 如何在 Grails Geb/Spock 测试用例中获取 sessionFactory?

    我想我需要在 GebSpec 测试中刷新 hibernate 会话 所以我想获取 sessionFactory 看起来应该被注入 但是当我做这样的事情时 class MySpec extends GebSpec def sessionFac
  • Grails 中不区分大小写的唯一约束

    我如何基本上对字符串数据类型字段执行唯一约束 class User String username String Email static hasMany roles Roles static constraints Email email
  • 修改String字段的getter的返回值

    假设我的应用程序中有一些类似于域类的类 其中包含一些 Long Double Date 和 String 字段 这些类使用一些公共字段和一些公共方法扩展了基类 每当我访问 String 类字段 通过 getter 时 我想对返回的值进行一些
  • 使用 JQuery 的 Grails 项目,无需插件

    我正在尝试设置一个简单的 Grails 2 1 1 应用程序 该应用程序将使用 JQuery 我有一个名为 TestController 的控制器和一个位于正确位置的index gsp 我手动添加 JQuery 库 没有使用 Grails
  • 如何在 Grails 中管理对象修订?

    我需要对我的文章实施修订系统grails网络应用程序 在搜索 grails 论坛 stackoverflow grails 插件和谷歌搜索互联网后 我最终得到了 3 个选项 Option 1 使用grails Envers 插件 see h
  • 如何在GEB中选择内部元素的文本?

    我有以下场景 div ul class select2 results style width 400px li class select2 results dept 0 select2 result select2 result sele
  • Grails GORM 和枚举

    我在 Grails 中使用枚举时遇到问题 我尝试在 grails 域对象中使用枚举 code package it xxx tools kanban import java util Date class Task String name
  • 使用 Grails GORM 从旧数据库中的 char 字段中去除尾随空格

    映射时去除尾随空格的可能解决方案有哪些char遗留数据库中的字段 我看到以下选项 Calling trim 在使用时 控制器 视图等 重写属性访问器以返回 trim 使用 Hibernate UserType 修剪空格 我倾向于重写属性访问
  • 在共享通用插件的两个 Grails 应用程序之间共享配置

    我们将有两个应用程序 它们都需要使用相同的服务 实用程序 代码 配置 我们使用 grailsApplication config 来配置外部服务的 URL 等内容 根据应用程序是否在 dev test qa staging prod 中运行
  • 本地 401 工作,临时服务器得到 302

    我可能不会获得帮助第一次尝试所需的所有信息 但我会尽我所能 并在我们进行过程中对其进行编辑 我有一个使用 Spring Security Core 插件的 Grails 1 3 7 应用程序 我正在编写处理会话超时和 ajax 请求的代码

随机推荐