Obecnie pracuję nad aplikacją Grails i pracuję z wtyczkami Spring Security i UI. Stworzyłem relację pomiędzy klasą użytkownika i innej klasy Area, że mam co widać poniżej:Grails - zapisz instancję przejściową przed wypróżnieniem Grails Error?
klasy użytkownika:
class User {
transient springSecurityService
String username
String email
String password
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired
static belongsTo = [area:Areas]
.......
}
palących Klasa:
class Areas {
String name
static hasMany = [users:User]
}
Jak widać z klas jeden użytkownik może być połączony z jednym obszarem, ale obszar może mieć wielu użytkowników. To wszystko działa dobrze i kiedy ładuję aplikację, wszystkie dane są dodawane poprawnie. Jednak pojawia się następujący błąd, gdy próbuję skorzystać z formularza w celu utworzenia nowego użytkownika:
object references an unsaved transient instance - save the transient instance before flushing: com.website.Area
poniżej jest kod kontroler używam, aby zapisać informacje:
def save = {
def user = lookupUserClass().newInstance(params)
if (params.password) {
String salt = saltSource instanceof NullSaltSource ? null : params.username
user.password = springSecurityUiService.encodePassword(params.password, salt)
}
if (!user.save(flush: true)) {
render view: 'create', model: [user: user, authorityList: sortedRoles()]
return
}
addRoles(user)
flash.message = "${message(code: 'default.created.message', args: [message(code: 'user.label', default: 'User'), user.id])}"
redirect action: edit, id: user.id
}
i tu jest próbkę tego, co GSP wygląda następująco:
<table>
<tbody>
<s2ui:textFieldRow name='username' labelCode='user.username.label' bean="${user}"
labelCodeDefault='Username' value="${user?.username}"/>
<s2ui:passwordFieldRow name='password' labelCode='user.password.label' bean="${user}"
labelCodeDefault='Password' value="${user?.password}"/>
<s2ui:textFieldRow name='email' labelCode='user.email.label' bean="${user}"
labelCodeDefault='E-Mail' value="${user?.email}"/>
<s2ui:textFieldRow readonly='yes' name='area.name' labelCode='user.area.label' bean="${user}"
labelCodeDefault='Department' value="${area.name}"/>
<s2ui:checkboxRow name='enabled' labelCode='user.enabled.label' bean="${user}"
labelCodeDefault='Enabled' value="${user?.enabled}"/>
<s2ui:checkboxRow name='accountExpired' labelCode='user.accountExpired.label' bean="${user}"
labelCodeDefault='Account Expired' value="${user?.accountExpired}"/>
<s2ui:checkboxRow name='accountLocked' labelCode='user.accountLocked.label' bean="${user}"
labelCodeDefault='Account Locked' value="${user?.accountLocked}"/>
<s2ui:checkboxRow name='passwordExpired' labelCode='user.passwordExpired.label' bean="${user}"
labelCodeDefault='Password Expired' value="${user?.passwordExpired}"/>
</tbody>
</table>
Patrzyłem na to i uważam, że jest to sposób próbuję zapisać obiekt Gorm i mam może zapisać rodzica (obszar) przed próbą zapisania użytkownik. Jednak Obszar zawsze będzie istniał, zanim użytkownik będzie mógł zostać utworzony, więc nie potrzebuję ponownego tworzenia obszaru, jak sobie z tym poradzić? Wypróbowałem funkcję "withTransaction" z niewielkim sukcesem.
Naprawdę doceniam pomoc, jeśli to możliwe.
Dzięki
EDIT ......
mam śledzone problemu do tej linii w kontrolerze:
RegistrationCode registrationCode = springSecurityUiService.register(user, command.password, salt)
to mówi mi, że ta funkcja jest wywołanie strzał dla obiektu użytkownika, jednak w przypadku istniejących relacji musi najpierw zapisać obszar. Czy ktoś zna SpringSecurityUi, aby mi w tym pomóc?
Dzięki
Umieść usługę springsecurity w kontrolerze, a nie w klasie domeny. – marko
Czy możesz podać mi przykład, proszę? ponieważ usługa springsecurity zawsze tam była – user723858
Czy błąd nie byłby powiązany z klasą "com.website.Area", jak mówi błąd? Dzięki – user723858