2012-12-07 1 views
0

도메인 클래스가 두 개 있는데 (예 : AccountMember) 올바른 연결 조합과 해당 관계를 모델링하는 mappedBy 속성을 찾는 데 문제가 있습니다. . 일반 영어의 경우 Account에는 기본 멤버가 하나뿐입니다. 또한 0 - 많은 부양 가족이 있습니다. 내가 인스턴스화하고 계정 및 회원을 유지하려고 할 때Grails의 동일한 도메인 클래스에 일대일 및 일대 다 연결

Account.groovy

class Account { 
    String displayId 

    Member primaryMember 
    SortedSet<Member> dependents = new TreeSet<Member>() 

    static belongsTo = [Member] 
    static hasMany = [dependents: Member] 
} 

Member.groovy

class Member implements Comparable<Member> { 
    MemberType memberType = MemberType.PRIMARY 
    String firstName 
    String lastName 

    static belongsTo = [account: Account] 

    @Override 
    int compareTo(Member m) { 
     return (this.memberType <=> m?.memberType) * 100 + (this.lastName <=> m?.lastName) * 10 + (this.firstName <=> m?.firstName) 
    } 
} 

이 문제가 발생합니다 내 최초의 시도처럼 보였다. 두 번째 테스트에 대한 데이터베이스 테이블이

계정

id | display_id 
1 | ABCDEFG 

처럼

id | first_name | last_name | member_type | account_id 
1 | John  | Smith  | Primary  | 1 
2 | Jane  | Smith  | Dependent | 1 
,536,913 회원을 보이기 때문에 예를 들어,

AccountIntegrationTests.groovy

class AccountIntegrationTests extends GroovyTestCase { 

    Account smiths 
    Member john 
    Member jane 

    @Before 
    void setup() {} 

    @Test 
    void testShouldLoadAccountWithNoDependents() { 
     // Arrange 
     smiths = new Account(displayId: "ABCDEFG") 

     john = new Member(firstName: "John", lastName: "Smith", memberType: MemberType.PRIMARY) 
     smiths.primaryMember = john 
     smiths.save(flush: true, failOnError: true) 

     def smithsId = smiths.id 
     smiths.discard() 

     // Act 
     def loadedSmiths = Account.get(smithsId) 

     // Assert 
     assert loadedSmiths.members.size() == 1 
     assert loadedSmiths.primaryMember == john 
     assert loadedSmiths.dependents.size() == 0 
    } 

    @Test 
    void testShouldLoadAccountWithOneDependent() { 
     // Arrange 
     smiths = new Account(displayId: "ABCDEFG") 
     john = new Member(firstName: "John", lastName: "Smith", memberType: MemberType.PRIMARY) 
     smiths.primaryMember = john 
     smiths.addToDependents(new Member(firstName: "Jane", lastName: "Smith", memberType: MemberType.DEPENDENT)) 
     smiths.save(flush: true, failOnError: true) 

     john = smiths.primaryMember 
     jane = smiths.dependents.first() 
     def smithsId = smiths.id 
     smiths.discard() 

     // Act 
     def loadedSmiths = Account.get(smithsId) 

     // Assert 
     assert loadedSmiths.members.size() == 2 
     assert loadedSmiths.primaryMember.firstName == "john" 
     assert loadedSmiths.dependents.size() == 1 
     assert loadedSmiths.dependents.first().firstName == "jane" 
    } 
} 

예외가 발생합니다

분명히 나는 ​​계정이 John을 기본 멤버로, Jane을 종속 멤버로 검색하려고하지만 GORM이 account.primaryMember를로드하려고 시도 할 때 계정 ID와 일치하는 여러 행 (Member 내)이 있다는 Hibernate 예외를 throw합니다 (1). 나는 두 단체를 구별하기 위해 mappedBy 판별이 필요하지만, 내가 시도 버전이 작동하지 않았다

나는 협회와 mappedBy 모두에 대해 GORM 설명서를 읽고

static mappedBy = [primaryMember: 'primaryMember', dependents: 'dependents'] 
- or - 
static mappedBy = [dependents: 'account'] 

계정뿐만 아니라, variousquestions on the site에 관해서는 multiple associations에서 same model까지, 불행하게도 그들은 모두 복수 hasMany의 연관성을 모델링하는 것처럼 보인다. 나는이 간단한 구현을 사용하기 위해 노력하고있어,하지만

class Person { 
    String name 

    static belongsTo = [team: Team] 
} 

class Team { 
    String name 

    static belongsTo = [coach: Person] 
    static hasMany = [players: Person] 
} 

: 동일 모델에 모두 일대와 일대일 관계를 참조 수행하는 사람은로 보여

--Output from testShouldLoadAccountWithNoDependents-- 
| Failure: testShouldLoadAccountWithNoDependents(AccountIntegrationTests) 
| org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: Account; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: Account 
    at AccountIntegrationTests.testShouldLoadAccountWithNoDependents(AccountIntegrationTests.groovy:26) 
Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: Account 
    ... 1 more 

AccountIntegrationTests.groovy:26smiths.save(flush: true, failOnError: true)입니다. 나는에 Team/Account 클래스를 수정하는 경우 :

class Team { 
    String name 
    Person coach 

    static hasMany = [players: Person] 
} 

나는 같은 예외가 발생했습니다, 그래서 나는 cascade의 일종이 필요하다 생각합니다.나는 추가 시도한 cascadeAccount :

계정

다음
static mapping = { 
    primaryMember cascade: 'all' 
    dependents cascade: 'all-delete-orphan' 
} 

나는 또한 이벤트 트리거를 사용하여 시도 :

계정 불행하게도

def beforeInsert() { 
    if (primaryMember?.isDirty()) { 
     primaryMember.save() 
    } 
} 

def beforeUpdate() { 
    if (primaryMember?.isDirty()) { 
     primaryMember.save() 
    } 
} 

를, 이러한 접근의도는 transient instance 해결 예외. 이것에 대한 어떤 도움이라도 대단히 감사하겠습니다.

답변

0

당황스럽게 간단한 해결책은 Member에서 static belongsTo = [account: Account]을 제거하는 것이 었습니다. 양방향 연결로 인해 문제가 발생했습니다.