Отображение Hibernate One-One с различными типами ключей - PullRequest
0 голосов
/ 31 августа 2018

У меня есть две таблицы USERS и USER_ROLES.

  CREATE TABLE USERS (
  ID          SERIAL PRIMARY KEY,
  USERNAME    VARCHAR(64)  NOT NULL UNIQUE,
  PASSWORD    VARCHAR(64)  NOT NULL,
  ENABLED     BOOLEAN      NOT NULL DEFAULT TRUE,
  EMAIL       VARCHAR(128) NOT NULL
);

CREATE TABLE USER_ROLES (
  USER_ROLE_ID SERIAL PRIMARY KEY,
  USERNAME     VARCHAR(64) NOT NULL UNIQUE REFERENCES USERS (USERNAME),
  ROLE         VARCHAR(32) NOT NULL
);

Как видите, username является ссылкой для userRole в Users сущности:

@Entity
public class Users {

    private int id;
    private String username;
    private String password;
    private boolean enabled;
    private String email;

    private UserRoles userRoles;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="username", insertable = false, updatable = false)
    public UserRoles getUserRoles() {
        return userRoles;
    }

    public void setUserRoles(UserRoles userRoles) {
        this.userRoles = userRoles;
    }

    @Id
    @Column(name = "id", nullable = false)
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Basic
    @Column(name = "username", nullable = false, length = 64)
    public String getUsername() {
        return username;
    }

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

    @Basic
    @Column(name = "password", nullable = false, length = 64)
    public String getPassword() {
        return password;
    }

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

    @Basic
    @Column(name = "enabled", nullable = false)
    public boolean isEnabled() {
        return enabled;
    }

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

    @Basic
    @Column(name = "email", nullable = false, length = 128)
    public String getEmail() {
        return email;
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Users users = (Users) o;
        return id == users.id &&
                enabled == users.enabled &&
                Objects.equals(username, users.username) &&
                Objects.equals(password, users.password) &&
                Objects.equals(email, users.email);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, username, password, enabled, email);
    }
}

и UserRole сущность:

@Entity
@Table(name = "user_roles")
public class UserRoles {
    private int userRoleId;
    private String role;
    private String username;

    Users users;

    @Id
    @Column(name = "user_role_id", nullable = false)
    public int getUserRoleId() {
        return userRoleId;
    }

    public void setUserRoleId(int userRoleId) {
        this.userRoleId = userRoleId;
    }

    @Basic
    @Column(name = "role", nullable = false, length = 32)
    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    @Basic
    @Column(name = "username", insertable = false, updatable = false)
    public String getUsername() {
        return username;
    }

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

    @OneToOne (optional=false, mappedBy="userRoles")
    public Users getUsers() { return users; }

    public void setUsers(Users users) {
        this.users = users;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserRoles that = (UserRoles) o;
        return userRoleId == that.userRoleId &&
                Objects.equals(role, that.role);
    }

    @Override
    public int hashCode() {
        return Objects.hash(userRoleId, role);
    }
}

И во время выполнения, когда я выполняю запрос: @Query("select b from Users b where b.username = :username"), я получаю следующую ошибку:

Caused by: org.postgresql.util.PSQLException: Bad value for type int : user
    at org.postgresql.jdbc.PgResultSet.toInt(PgResultSet.java:2831)
    at org.postgresql.jdbc.PgResultSet.getInt(PgResultSet.java:2088)
    at org.postgresql.jdbc.PgResultSet.getInt(PgResultSet.java:2502)
    at com.zaxxer.hikari.pool.HikariProxyResultSet.getInt(HikariProxyResultSet.java)

Я знаю, эта ошибка появляется, потому что что-то не так с внешними / первичными ключами и Hibernate пытается сопоставить целое число с varchar. Но как я могу решить эту проблему?

Схема базы данных:

db screen

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Я решил свою проблему. Как ни печально, причина была в неправильных типах первичного ключа в таблице user_roles. Когда я изменил аннотации к методу-получателю для сущности Users в UserRoles, он работал как предполагалось:

    @OneToOne
    @JoinColumn(name="user_role_id")
    public UserEntity getUserEntity() { return userEntity; }
0 голосов
/ 31 августа 2018

Я думаю, что вам не хватает @Table(name="users") на вашем Users.java, а Hibernate не знает, как его отобразить.

...