假设我有两个对象,比如一个是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对象添加状态?
答案 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;