gpt4 book ai didi

spring - Grails TransientObjectException

转载 作者:行者123 更新时间:2023-12-02 14:07:36 25 4
gpt4 key购买 nike

这与this post有关,您将在其中找到许多我的配置。 ldap用户被映射到数据库用户表,并且条目创建良好。然后,userDetails尝试从主用户类获取权限,从而导致以下异常:

2014-01-31 12:10:52,076 [http-bio-8111-exec-4] ERROR [/step].[default]  - Servlet.service() for servlet [default] in context with path [/step] threw exception
Message: object references an unsaved transient instance - save the transient instance before flushing: packagae.User; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: package.User
Line | Method
->> 102 | doCall in org.grails.datastore.gorm.GormStaticApi$_methodMissing_closure2
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 42 | getAuthorities in package.User
| 27 | getAuthorities . . . in package.MdtUserDetails
| 72 | attemptAuthentication in grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter
| 49 | doFilter . . . . . . in ''
| 82 | doFilter in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
| 1145 | runWorker . . . . . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 744 | run . . . . . . . . . in java.lang.Thread
Caused by TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: package.User
->> 102 | doCall in org.grails.datastore.gorm.GormStaticApi$_methodMissing_closure2
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 42 | getAuthorities in package.User
| 27 | getAuthorities . . . in package.MdtUserDetails
| 72 | attemptAuthentication in grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter
| 49 | doFilter . . . . . . in ''
| 82 | doFilter in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
| 1145 | runWorker . . . . . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 744 | run . . . . . . . . . in java.lang.Thread

这是我的用户详细信息类:
import java.util.Collection;

import org.springframework.security.core.GrantedAuthority
import org.springframework.security.ldap.userdetails.LdapUserDetails

import package.Role
import package.User

class MdtUserDetails extends User implements LdapUserDetails{



public MdtUserDetails(String fullName, String email, String username, String password, boolean enabled, boolean accountExpired,
boolean accountLocked, boolean passwordExpired, Collection<GrantedAuthority> authorities) {
super(username: username, password: password, email: email, fullName: fullName, enabled: enabled, accountExpired: accountExpired, accountLocked: accountLocked, passwordExpired: passwordExpired, authorties: authorities)

}


@Override
public Set<Role> getAuthorities(){
return super.getAuthorities()
}

@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return false;
}

@Override
public String getDn() {
// TODO Auto-generated method stub
return null;
}


}

和用户:
class User {

transient springSecurityService

String username
String toString() {
"${username}"
}
String password
String email
String fullName
String userOrg
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired

static belongsTo = [organization : Organization]
static hasMany = [reports: Report, invoices: Invoice]

static mappedBy = [invoices:'lastUpdatedBy', reports: 'lastUpdatedBy']
static transients = ['springSecurityService']

static constraints = {
username blank: false, unique: true
//have to nullable true the password in order to map mdtUsers to applicaiton roles.
password nullable: true, blank: true
email blank: true, nullable: true
fullName nullable: true, blank: true
userOrg nullable: true, blank: true
organization nullable: true, blank: true
}

static mapping = {
table 'step_users'
password column: '`password`'
}

Set<Role> getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}

def beforeInsert() {
encodePassword()
}

def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}

protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}

我不确定这是否与级联事件有关,或者我应该如何保存 session ,或者我如何在UserDetails中调用父类(super class)?

编辑

终于想通了!

在UserDetails类中,我扩展了自己的用户类:
import package.User

class MdtUserDetails extends User {

相反,我需要从这里扩展springsecurity用户类:
import org.springframework.security.core.userdetails.User

我认为这是导致我的Transient对象异常的原因,因为答案表明您需要拥有belongsTo,等等。我的确在类中包含了这些对象。

最佳答案

Caused by TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: package.User

此消息告诉您要保存的 User对象至少包含对另一个未保存的域对象的引用。

根据您的 User类,此未保存的引用可以是 ReportInvoice对象。
您可以使用以下选项来解决此问题:

在将报表和发票添加到用户之前,手动保存它们



启用使用以下命令自动级联报告和发票
static mapping = {
reports cascade: 'all-delete-orphan'
reports invoices: 'all-delete-orphan'
}



belongsToInvoice中添加 Report关系:
static belongsTo = [user: User]

关于spring - Grails TransientObjectException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21488376/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com