2013-10-26 3 views
0

GORM에서 Foo와 Bar 도메인 간의 양방향 일대 다 관계를 만들려고합니다.GORM 양방향 일대 다

가 여기에 지금까지이 작업은 다음과 같습니다

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

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

나는 관계의 방법을 사용하여 갈 때 I는 데 문제를, 그들은 내가 그들이해야 생각하는 방식으로 작동하지 않는 것. 예를 들어, "foo.bars.add (bar)"와 같은 명령문이 bar 인수에 foo 필드를 설정한다고 생각할 수 있습니다. 그러나 "bar.foo.id"라고 부를 때 foo 필드가 null이라고 들었습니다. "foo.bars.add (bar)"대신 "bar.foo = foo"를 사용하면이 문제를 해결할 수 있습니다.

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.bars.size"를 호출 할 때 불행하게도, 그것은 0

은 내가 무슨 말을 명확하게 파악할 것을 저에게 말한다, 여기 내 시험이다

내가 뭘 잘못하고 있니?

참고 : 통합 테스트를 통해이를 실행하고 있습니다. 또한 "foo.addToBars (bar)"는 "foo.bars.add (bar)"및 "bar.foo = foo"가 작동해야한다고 생각하는 방식으로 작동합니다.

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; 
    } 
} 
+0

나는 Hibernate와 JPA를 사용하여 같은 "실험"을 시도했지만 같은 결과를 얻었다. Java 관점에서 볼 때 많은 요소가 들어있는 컨테이너는 관계의 다른 쪽에서 값을 설정하는 방법을 알 수 없습니다. (즉, bar.foo = foo) 데이터베이스의 관점에서 볼 때 이는 의미가 없습니다. "foo.bars"를 호출하면 SQL 쿼리 "SELECT * FROM Bar WHERE foo_id = : foo_id"도 실행하지 않습니까? 그런 경우 bar 객체의 foo 필드를 설정해야합니다. 그러나 그렇지 않습니다. 그리고 foo.bars에는 막대가 있습니다. – tygerpatch

답변

2

당신 read the documentation 경우 해당를 배울 당신이 발견으로,하지만 여전히 의문을 제기하고 있습니다 :

업데이트는 여기에 내가 (최대 절전 모드와 JPA를 사용하여) 원하는 것을 내가 한 빠른 해킹 컬렉션에 항목을 추가하여 올바르게 유지되도록하는 올바른 방법은 addTo* 메서드를 사용하는 것입니다.

따라서 귀하의 경우에 addToBars을 사용했다고 가정하면 이것이 올바른 방법입니다. 즉, 당신이 취하는 성과가 있습니다. 또 다른 방법은 다음과 같습니다.

bar.foo = foo 
bar.save() 

단점은 foo가 기존 Set에 bar를 포함하지 않는다는 것입니다. 데이터베이스에서 다시 가져와야합니다. 그것은 약간의주고 받기이며 당신은 당신의 상황에 가장 적합한 방법을 사용합니다.

+0

문서에서 addTo * 메소드가 컬렉션에 항목을 추가하는 올바른 방법이라고 말하는 곳은 어디입니까? addTo *에 대한 문서에서는 양방향 관계의 양면을 설정한다고 설명합니다. – tygerpatch

+0

네, 양쪽면 모두를 원한다면, 그것은 당신이해야 할 일입니다. – Gregg

관련 문제