【问题标题】:JPA User, Role, manyToMany hibernate relationshipJPA 用户、角色、多对多休眠关系
【发布时间】:2017-09-21 21:14:33
【问题描述】:

我正在使用 JPA+Hibernate+SpringBoot+PostgreSQL 在不同实体之间创建关系,但我遇到了大量错误,包括看起来像 SQL 错误的错误,但应用程序还是启动了。我是否正确编码了 manyToMany 关系?可能有很多用户,每个用户可以有多个角色。也许 OneToMany 更好?

我正在使用“spring-boot-starter-data-jpa”

这些是我目前仅有的休眠文件。

Role.java

@Entity(name = "role")
public class Role implements java.io.Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = -5525359165179861924L;
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name = "id")
    int id;

    private String role;

    @ManyToMany(mappedBy = "roles",fetch = FetchType.LAZY)
    private Set<User> users;


    public Role(String role) {
        super();
        this.role = role;
    }

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

    public int getId(){
        return id;
    }

    public String getRole() {
        return role;
    }

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

    public Set<User> getUsers() {
        return users;
    }

    public void setUser(Set<User> users) {
        this.users = users;
    }
}

User.java

@Entity
@Table(name = "user")
public class User implements java.io.Serializable {

    private static final long serialVersionUID = 4910225916550731448L;

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

    @Column(name = "created")
    Date created;

    @Column(name = "firstName", length = 100)
    private String firstName;

    @Column(name = "lastName", length = 100)
    private String lastName;

    @Column(name = "email", length = 150)
    private String email;

    @Column(name = "username", length = 150)
    private String username;

    @Column(name = "enabled")
    private int enabled;

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(joinColumns = @JoinColumn(name = "userId", referencedColumnName = "id"), 
    inverseJoinColumns = @JoinColumn(name = "roleId", referencedColumnName = "id"))
    private Set<Role> roles;

    protected User(){
        roles = new HashSet<Role>();
    }

    public Set<Role> getRoles(){
        return roles;
    }

    public void setRoles(Set<Role> roles){
        this.roles = roles;
    }

    public User(String firstName, String lastName, String email, String username, Set<Role> roles) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.username = username;
        this.roles = roles;
    }
}

我得到的错误:

2017-04-24 22:49:19.163  WARN 20488 --- [  restartedMain] org.hibernate.orm.deprecation            : HHH90000014: Found use of deprecated [org.hibernate.id.SequenceGenerator] sequence-based id generator; use org.hibernate.id.enhanced.SequenceStyleGenerator instead.  See Hibernate Domain Model Mapping Guide for details.
2017-04-24 22:49:19.167  WARN 20488 --- [  restartedMain] org.hibernate.orm.deprecation            : HHH90000014: Found use of deprecated [org.hibernate.id.SequenceGenerator] sequence-based id generator; use org.hibernate.id.enhanced.SequenceStyleGenerator instead.  See Hibernate Domain Model Mapping Guide for details.
2017-04-24 22:49:19.438  INFO 20488 --- [  restartedMain] org.hibernate.tuple.PojoInstantiator     : HHH000182: No default (no-argument) constructor for class: com.example.domain.Role (class must be instantiated by Interceptor)
2017-04-24 22:49:19.527  INFO 20488 --- [  restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000227: Running hbm2ddl schema export
Hibernate: alter table user_roles drop constraint FKrhfovtciq1l558cw6udg0h0d3
2017-04-24 22:49:19.531 ERROR 20488 --- [  restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000389: Unsuccessful: alter table user_roles drop constraint FKrhfovtciq1l558cw6udg0h0d3
2017-04-24 22:49:19.531 ERROR 20488 --- [  restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport  : ERROR: relation "user_roles" does not exist
Hibernate: alter table user_roles drop constraint FK55itppkw3i07do3h7qoclqd4k
2017-04-24 22:49:19.532 ERROR 20488 --- [  restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000389: Unsuccessful: alter table user_roles drop constraint FK55itppkw3i07do3h7qoclqd4k
2017-04-24 22:49:19.533 ERROR 20488 --- [  restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport  : ERROR: relation "user_roles" does not exist
Hibernate: drop table if exists role cascade
Hibernate: drop table if exists user cascade
2017-04-24 22:49:19.535 ERROR 20488 --- [  restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000389: Unsuccessful: drop table if exists user cascade
2017-04-24 22:49:19.535 ERROR 20488 --- [  restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport  : ERROR: syntax error at or near "user"
  Position: 22
Hibernate: drop table if exists user_roles cascade
Hibernate: drop sequence hibernate_sequence
2017-04-24 22:49:19.537 ERROR 20488 --- [  restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000389: Unsuccessful: drop sequence hibernate_sequence
2017-04-24 22:49:19.538 ERROR 20488 --- [  restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport  : ERROR: sequence "hibernate_sequence" does not exist
Hibernate: create sequence hibernate_sequence start 1 increment 1
Hibernate: create table role (id int4 not null, role varchar(255), primary key (id))
Hibernate: create table user (id int8 not null, created timestamp, email varchar(150), enabled int4, first_name varchar(100), last_name varchar(100), username varchar(150), primary key (id))
2017-04-24 22:49:19.564 ERROR 20488 --- [  restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000389: Unsuccessful: create table user (id int8 not null, created timestamp, email varchar(150), enabled int4, first_name varchar(100), last_name varchar(100), username varchar(150), primary key (id))
2017-04-24 22:49:19.564 ERROR 20488 --- [  restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport  : ERROR: syntax error at or near "user"
  Position: 14
Hibernate: create table user_roles (user_id int8 not null, role_id int4 not null, primary key (user_id, role_id))
Hibernate: alter table user_roles add constraint FKrhfovtciq1l558cw6udg0h0d3 foreign key (role_id) references role
Hibernate: alter table user_roles add constraint FK55itppkw3i07do3h7qoclqd4k foreign key (user_id) references user
2017-04-24 22:49:19.585 ERROR 20488 --- [  restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000389: Unsuccessful: alter table user_roles add constraint FK55itppkw3i07do3h7qoclqd4k foreign key (user_id) references user
2017-04-24 22:49:19.585 ERROR 20488 --- [  restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport  : ERROR: syntax error at or near "user"
  Position: 100
2017-04-24 22:49:19.585  INFO 20488 --- [  restartedMain] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000230: Schema export complete

【问题讨论】:

  • user 是关键字。你不能用那个名字作为你的表名。
  • 使用反引号转义表名。

标签: java spring hibernate jpa


【解决方案1】:

首先你应该删除你的数据库或者改变你的休眠配置来创建

<prop key="hibernate.hbm2ddl.auto">create</prop>

错误是

ERROR: relation "user_roles" does not exist

所以您应该将 ManyToMany 命名为 user_roles

@JoinTable(name="user_roles",
        joinColumns = {@JoinColumn(name="user_id", referencedColumnName="id")},
        inverseJoinColumns = {@JoinColumn(name="role_id", referencedColumnName="id")}
    )
    private List<Role> roles;

在我的项目中用户实体是:

  @Entity
@Table(name = "user")
public class User extends AbstractPersistable<Long>{


    private static final long serialVersionUID = 1L;


    @Column(name = "USER_NAME", unique = true)
    private String username;
    @Column(name = "PASSWORD")
    private String password;



    @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
    @JoinTable(name="user_roles",
        joinColumns = {@JoinColumn(name="user_id", referencedColumnName="id")},
        inverseJoinColumns = {@JoinColumn(name="role_id", referencedColumnName="id")}
    )
    private List<Role> roles;



    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 List<Role> getRoles() {
        return roles;
    }



    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }



    public User(String username, String password, List<Role> roles) {
        super();
        this.username = username;
        this.password = password;
        this.roles = roles;
    }



    public User() {
        super();
    }
}

和角色:

 @Entity
@Table(name = "roles")
public class Role extends AbstractPersistable<Long> {

    private static final long serialVersionUID = 1L;

    private String role;

    public String getRole() {
        return role;
    }

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

    public Role() {
    }

    public Role(String role) {
        this.role = role;
    }

}

【讨论】:

  • 你的文件里怎么没有Id的东西?你也没有实现可序列化但你扩展 AbstractPersistable ?
  • 自动生成的Id是从AbstractPersistable扩展而来的,AbstractPersistable实现了Serializable
  • 当我尝试添加一个现有角色和一个不存在的角色时,仍然存在添加角色分离实体持久性问题的一些问题。但也许我应该将其更改为 OneToMany
  • 在oneToMany的情况下你不需要joinTable
  • 是的。我只是为了测试而摆脱它。但是您的代码和 OneToMany 都有效。我遇到的问题是persist-vs-merge,如果您尝试创建“新”用户和新角色以及现有角色,并尝试使用Cascade.ALL,它会导致持久问题。谢谢帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-22
  • 1970-01-01
  • 2015-07-21
  • 1970-01-01
相关资源
最近更新 更多