繁体   English   中英

休眠实体中的映射外键

[英]Mapped foreign key in Hibernate Entity

嗨,请使用Spring Security编写Spring应用程序。 这是我的用户和帐户角色数据库:

create table users (

  id int not null primary key,
  username varchar2(20) not null unique,
  password varchar2(20) not null,
  firstName varchar2(20),
  lastName varchar2(20),
  personalId varchar2(11) unique,
  city varchar2(40),
  address varchar2(40),
  email varchar2(30) unique,
  phone varchar2(9) unique,
  enabled number(1) not null
);

create table user_roles (
  id int primary key,
  name varchar2(20) not null,
  username varchar(20) constraint username_fk references users(username) not null
);

我的实体类:

@Entity
@Table(name = "users")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue
    @Column(name = "id")
    private Integer id;
    @NotNull
    @Column(name = "username")
    private String username;
    @NotNull
    @Column(name = "password")
    private String password;
    @Column(name = "firstName")
    private String firstName;
    @Column(name = "lastName")
    private String lastName;
    @Column(name = "personalId")
    private String personalId;
    @Column(name = "city")
    private String city;
    @Column(name = "address")
    private String address;
    @Column(name = "email")
    private String email;
    @Column(name = "phone")
    private String phone;
    @NotNull
    @Column(name = "enabled")
    private int enabled;
    @OneToMany(mappedBy = "username")
    private Set<UserRole> userRoleSet = new HashSet<UserRole>(0);

@Entity
@Table(name = "user_roles")
public class UserRole implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Integer id;
    @NotNull
    @Column(name = "name")
    private String name;
    @JoinColumn(name = "username")
    @ManyToOne(targetEntity = User.class)
    private String username;

当我尝试登录我的系统时出现错误:

休眠:从user_roles userrolese0_中选择userrolese0_.username作为username3_1_0_,userrolese0_.id作为id1_0_0_,userrolese0_.id作为id1_0_1_,userrolese0_.name作为name2_0_1_,userrolese0_.username作为username3_0_1_,其中userrolese0_.user =? 警告:org.hibernate.engine.jdbc.spi.SqlExceptionHelper-SQL错误:1722,SQLState:42000错误:org.hibernate.engine.jdbc.spi.SqlExceptionHelper-ORA-01722:无效的数字

我的课程实现了UserDetailsS​​ervice:

    package pl.piotr.ibank.service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import pl.piotr.ibank.daointerface.UserDao;
import pl.piotr.ibank.model.UserRole;

@Transactional(readOnly = true)
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    UserDao userDao;

    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {

        pl.piotr.ibank.model.User user = userDao.findByUsername(username);

        List<GrantedAuthority> authorities = buildUserAuthority(user
                .getUserRole());

        return buildUserForAuthentication(user, authorities);

    }

    private List<GrantedAuthority> buildUserAuthority(Set<UserRole> userRoles) {
        Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();

        for (UserRole userRole : userRoles) {
            setAuths.add(new SimpleGrantedAuthority(userRole.getName()));
        }

        List<GrantedAuthority> result = new ArrayList<GrantedAuthority>(
                setAuths);
        return result;
    }

    private UserDetails buildUserForAuthentication(
            pl.piotr.ibank.model.User user, List<GrantedAuthority> authorities) {
        return new User(user.getUsername(), user.getPassword(), true, true,
                true, true, authorities);
    }

    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

我认为是这样,我映射的表的forgin键是不好的。 from User示例查询from User表返回用户,但是当我尝试获取user_roles时,出现上述错误。 请检查我映射的正确性。 我使用Oracle数据库和Hiberante。

问题是,当您映射实体时,Hibernate期望外键是所引用实体的ID,即您应该映射为用户ID而不是用户名。

同样,您的实体映射似乎是错误的:您使用目标对象为User的ManyToOne,但属性的类型为String AFAIK Hibernate会尝试将用户分配给username ,这将导致失败。

因此,该表应如下所示:

create table user_roles (
  id int primary key,
  name varchar2(20) not null,
  userid int constraint userid_fk references users(id) not null
);

然后, UserRole的映射应为:

@JoinColumn(name = "userid")
@ManyToOne
private User user;

加上User的反向映射:

@OneToMany(mappedBy = "user")
private Set<UserRole> userRoleSet;

另外请注意, id是HQL中的特殊关键字,即,它将始终引用实体的id。 如果id始终是唯一用@Id注释的属性,那么这没问题,但是如果您进行更改,则在选择错误数据甚至失败时查询都可能会遇到问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM