도메인 클래스가 두 개 있는데 (예 : Account
및 Member
) 올바른 연결 조합과 해당 관계를 모델링하는 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:26
은 smiths.save(flush: true, failOnError: true)
입니다. 나는에 Team/Account
클래스를 수정하는 경우 :
class Team {
String name
Person coach
static hasMany = [players: Person]
}
나는 같은 예외가 발생했습니다, 그래서 나는
cascade
의 일종이 필요하다 생각합니다.나는 추가 시도한
cascade
에
Account
:
계정
다음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
해결 예외. 이것에 대한 어떤 도움이라도 대단히 감사하겠습니다.