Reputation: 1688
I have two domain classes where i want a unidirectional relationship from each to the other:
class User {
HistoryEntry lastFooEntry
static constraints = {
lastFooEntry(nullable: true)
}
}
class HistoryEntry {
String name
User createdBy
}
According to the grails documentation (as i understand it) this is the way to do it. Specifying belongsTo
would create a bidirectional relationship (what i don't want) and hasOne
only works with bidirectional relationships anyway.
The problem with the above modelling is, that the following code only works when entryName=='foo'
. For any other value the assertion is false:
def addHistoryEntry(Long id, String entryName) {
def user = User.get(id)
if(!user) {
user = new User(id: id).save()
}
def entry = new HistoryEntry(createdBy: user, name: entryName).save()
if(entryName=='foo') {
user.lastFooEntry = entry
user.save()
} else {
assert user.lastFooEntry!=entry
}
}
I can work around this by specifying
static mappedBy = [createdBy:'']
in HistoryEntry
. But according to IntelliJ IDEA and the grails documentation this should only be used in conjunction with hasMany
and I've never seen it with an empty string.
So the question: What is the right way to do this? Or is it a undocumented feature / bug and my workaround is fine so far?
Upvotes: 0
Views: 380
Reputation: 13475
If you don't specify a field on the other side of relationship, relationship will remain unidirectional in terms of JVM - i.e. your example is suffficient and you need nothing more. hasOne
in User
or/and belongsTo
in HistoryEntry
will also work.
The example is probably missing something, because the assertion cannot be false: the entry
was just created, and never assigned to anything, so it's impossible for that User
or any other object to reference it. Moreover, entry
is not saved or flushed yet.
Whether a 1:1 relationship in relational database is 1-directional or 2-directional is more a question of interpretation: normally you only have foreign key only on one end, but the other way can also be calculated.
So don't worry, Grails will never auto-add a reference field on ther other end of a relationship unless you declare that field explicitly.
Upvotes: 1