在不创建新对象的情况下将对象A中的对象添加到对象B中? HIBERNATE

时间:2017-06-22 14:01:11

标签: java hibernate one-to-many hibernate-mapping cascade

假设我有两个对象,比如一个是User对象,另一个是State对象。国家对象基本上是美国的50个州,因此它不需要改变。但是,用户对象具有用户所在的状态集合。像这样:

@Entity
@Table(name="tbl_users")
class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id", unique=true, nullable = false)
    private int id;

    @Column(name="user_name")
    private String name;

    @OneToMany(targetEntity=State.class, orphanRemoval = false)
    @Column(name="states")
    private Collection<State> states;

    //getters and setters
}

并且州实体看起来像这样:

@Entity
@Table(name="tbl_states")
class State {

   @Id
   @Column(name="id", unique=true, nullable=false)
   private int id;

   @Column(name="state")
   private String state;

   // getters and setters
}

添加用户的代码(使用休眠):

public int addUser(User user) {
    em.persist(user);
    em.flush();
    return user.getId();
}

通过id获取州的代码:

public State getStateById(int id) {
    return em.createQuery("SELECT s FROM State s WHERE s.id =:id, State.class)
            .setParameter("id", id)
            .getSingleResult();
}

但是当我尝试创建一个用户并选择几个状态时,我得到一个PSQLException:

org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "uk_g6pr701i2pcq7400xrlb0hns"
2017-06-21T22:54:35.959991+00:00 app[web.1]:   Detail: Key (states_id)=(5) already exists.

我尝试查找Cascade方法以查看是否可以使用任何方法,但Cascade.MERGE和Cascade.PERSIST似乎做同样的事情,其余我认为我不需要(REMOVE,DETACH等) 。我的问题是: 如何在没有错误的情况下向User对象添加状态?

2 个答案:

答案 0 :(得分:1)

此代码有效:

TextBlock

您应该将映射更改为@ManyToMany!

你必须在DB上有3个表,如下所示: TBL_USERS,TBL_STATES和TBL_USERS_TBL_STATES

TBL_USERS_TBL_STATES表是Hibernate在使用@ManyToMany注释属性时使用的默认表名。如果要更改TBL_USERS_TBL_STATES的表名,请同时使用@JoinTable注释。请参阅文档here

使用此配置,您应该能够从数据库中获取状态,将其添加到新用户,然后将其保留。我做了一个单元测试,它有效!

答案 1 :(得分:0)

在你的情况下,最好使用与多种休眠相关的多种关联,不要产生单一性约束。

使用onetoMany时,Hibernate自动生成方案行为有点奇怪,但您可以使用此解决方法。

试试这个:

@ManyToMany 
@JoinTable(name = "user_state") 
private List<State> states;