TransientPropertyValueException:对象引用了未保存的瞬态实例 - 在刷新之前保存瞬态实例

Posted

技术标签:

【中文标题】TransientPropertyValueException:对象引用了未保存的瞬态实例 - 在刷新之前保存瞬态实例【英文标题】:TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing 【发布时间】:2019-01-14 03:37:00 【问题描述】:

我正在尝试将用户详细信息存储到下表中:用户、角色、用户角色。尝试保存详细信息时,会引发以下错误。

托管刷新期间出错 [org.hibernate.TransientPropertyValueException:对象引用了一个 未保存的瞬态实例 - 之前保存瞬态实例 冲洗

这里 user_role 是父表,用户和角色表是子表。我尝试使用 cascade = CASCADE.ALL。即使它会引发同样的错误。

用户.java

@Entity
public class User implements UserDetails, Serializable

    private static final long serialVersionUID = 902783495L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="Id", nullable=false, updatable = false)
    private Long id;

    private String username;
    private String password;
        private String email;

    private boolean enabled = true;

    @OneToMany(mappedBy = "user", cascade=CascadeType.ALL, fetch = FetchType.EAGER)
    @JsonIgnore
    private Set<UserRole> userRoles = new HashSet<>();

    public Long getId() 
        return id;
    

    public void setId(Long id) 
        this.id = id;
    

    public String getUsername() 
        return username;
    

    public void setUsername(String username) 
        this.username = username;
    

    public String getPassword() 
        return password;
    

    public void setPassword(String password) 
        this.password = password;
    



    public void setEnabled(boolean enabled) 
        this.enabled = enabled;
    

    public Set<UserRole> getUserRoles() 
        return userRoles;
    

    public void setUserRoles(Set<UserRole> userRoles) 
        this.userRoles = userRoles;
    

        public String getEmail() 
        return email;
    

    public void setEmail(String email) 
        this.email = email;
    

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() 

        Set<GrantedAuthority> authorities = new HashSet<>();
        userRoles.forEach(ur -> authorities.add(new Authority(ur.getRole().getName())));

        return authorities;
    

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

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

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

    @Override
    public boolean isEnabled() 
        return enabled;
    





角色.java

@Entity
public class Role implements Serializable

    private static final long serialVersionUID = 890245234L;

    @Id
    private int roleId;

    private String name;

    @OneToMany(mappedBy = "role", cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<UserRole> userRoles = new HashSet<>();

    public Role()

    public int getRoleId() 
        return roleId;
    

    public void setRoleId(int roleId) 
        this.roleId = roleId;
    

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public Set<UserRole> getUserRoles() 
        return userRoles;
    

    public void setUserRoles(Set<UserRole> userRoles) 
        this.userRoles = userRoles;
    



UserRole.java

@Entity
@Table(name="user_role")
public class UserRole implements Serializable 
    private static final long serialVersionUID = 890345L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long userRoleId;

    public UserRole () 

    public UserRole (User user, Role role) 
        this.user = user;
        this.role = role;
    

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne(fetch = FetchType.EAGER)
    private Role role;

    public long getUserRoleId() 
        return userRoleId;
    

    public void setUserRoleId(long userRoleId) 
        this.userRoleId = userRoleId;
    

    public User getUser() 
        return user;
    

    public void setUser(User user) 
        this.user = user;
    

    public Role getRole() 
        return role;
    

    public void setRole(Role role) 
        this.role = role;
    



【问题讨论】:

能否请您也为您的项目包括 UserDetails 和 pom.xml 另外,你真的需要创建用户角色实体吗?如果您更改此 public Set getUserRoles() return userRoles; 它应该默认创建。 与 Set 而不是 UserRole 的相同关系。然后休眠将创建一个名为 User_Role 的新表,其中将在表中包含 user_id 和 ROle_id id。只是想在这里简化设计。 【参考方案1】:

这里的 role_id 是主键,您每次都尝试将 1 设置为 role_id,使用 @ID @GeneratedValue(策略 = GenerationType.AUTO) 私人长序列号;

【讨论】:

以上是关于TransientPropertyValueException:对象引用了未保存的瞬态实例 - 在刷新之前保存瞬态实例的主要内容,如果未能解决你的问题,请参考以下文章