grails - GORM双向一对多

标签 grails gorm

我正在尝试在GORM中的Foo和Bar域之间创建双向一对多关系。

这是我到目前为止的内容:

class Bar {
   static belongsTo = [foo: Foo]
}

class Foo {
   Set bars = []
   static hasMany = [bars: Bar]
}

我遇到的问题是,当我去使用关系方法时,它们似乎没有按照我认为的方式表现。例如,您会认为类似“foo.bars.add(bar)”的语句也会在bar参数上设置foo字段。但是当我调用“bar.foo.id”时,我被告知foo字段为空。如果我使用“bar.foo = foo”而不是“foo.bars.add(bar)”,则可以解决该问题。不幸的是,当我调用“foo.bars.size()”时,它告诉我它是0。

为了更清楚地了解我在说什么,这里是我的测试:
def testFoo() {
   def foo = new Foo()
   def bar = new Bar()

   foo.bars.add(bar)

   println "foo.bars.size() = ${foo.bars.size()}"
   println "bar.id = ${bar.id}"

   for(def xbar : foo.bars) {
      println "bar.id = ${xbar.id}"
   }

   println "foo.id = ${foo.id}"
   println "bar.foo.id = ${bar?.foo?.id}" // <- is null
}

def testBar() {
   def foo = new Foo()
   def bar = new Bar()

   bar.foo = foo

   println "foo.bars.size() = ${foo.bars.size()}" // <- is 0
   println "bar.id = ${bar.id}"

   for(def xbar : foo.bars) {
      println "bar.id = ${xbar.id}"
   }

   println "foo.id = ${foo.id}"
   println "bar.foo.id = ${bar?.foo?.id}"
}

我究竟做错了什么?

注意:我正在通过集成测试来运行它。我还发现,“foo.addToBars(bar)”的工作方式与我认为“foo.bars.add(bar)”和“bar.foo = foo”的工作方式相同。

更新这是我做的一个快速修改,可以实现我想要的功能(使用Hibernate和JPA):
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedList;

import stuff.Foo;

public class MyList<Bar> extends LinkedList {

   private Foo foo;

   public MyList(Foo foo) {
      this.foo = foo;
   }

   @Override
   public boolean add(Object obj) {
      boolean result = super.add(obj);

      try {
         Method barMethod = obj.getClass().getDeclaredMethod("setFoo", Foo.class);
         barMethod.invoke(obj, foo);
      }
      catch(NoSuchMethodException noSuchMethod) {
         noSuchMethod.printStackTrace();
      }
      catch(InvocationTargetException invocationTarget) {
         invocationTarget.printStackTrace();
      }
      catch(IllegalAccessException illegalAccess) {
         illegalAccess.printStackTrace();
      }

      return result;
   }
}

最佳答案

如果您使用read the documentation,您将了解到,但仍在质疑中,将项目添加到集合中以便正确保存的正确方法是使用addTo*方法。

因此,在您的情况下,当您说使用addToBars有效时,这是正确的方法。也就是说,您会因此受到一些性能上的影响。另一种方法是:

bar.foo = foo
bar.save()

缺点是foo在其现有Set中将不包含bar。您必须再次将其从数据库中拉出。这是一个让步,您只是使用适合您情况的最佳方法。

关于grails - GORM双向一对多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19612725/

相关文章:

grails - 如何在 Grails 3.3.0 中集成 paypal 支付网关

grails - Grails性能测试错误:org.hibernate.StaleObjectStateException:行被另一个事务更新或删除

sql-server - Grails将String映射到nvarchar

grails - grails/gorm消息捆绑问题

grails - Grails中的自定义联接表

oracle - GORM-使用订单和锁定选择最大记录-ORA-02014

Grails - 分隔字符串的多个复选框

grails - Windows 7 命令提示符使用 geb 和 spock 运行 grails 功能测试

grails - Grails GORM通过Domain映射内的值查找

templates - Grails:模板与 TagLib。