Java 将对象A中的对象添加到对象B中而不创建新对象?冬眠
假设我有两个对象,一个是用户对象,另一个是状态对象。州的目标基本上是美国的50个州,所以它永远不需要改变。然而,用户对象有一个用户所在的状态集合。所以像这样:Java 将对象A中的对象添加到对象B中而不创建新对象?冬眠,java,hibernate,one-to-many,hibernate-mapping,cascade,Java,Hibernate,One To Many,Hibernate Mapping,Cascade,假设我有两个对象,一个是用户对象,另一个是状态对象。州的目标基本上是美国的50个州,所以它永远不需要改变。然而,用户对象有一个用户所在的状态集合。所以像这样: @Entity @Table(name="tbl_users") class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="id", unique=true, nullable = false) pr
@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
}
用于添加用户的代码(使用hibernate):
按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似乎做了相同的事情,其余的我认为不需要(删除、分离等)。我的问题是:
如何向用户对象添加状态而不出现该错误?在您的情况下,最好使用多个hibernate dont generate unicity约束的多个关联 对于onetoMany,Hibernate自动生成方案的行为有点奇怪,但您可以使用此解决方法 试试这个:
@ManyToMany
@JoinTable(name = "user_state")
private List<State> states;
@manytomy
@JoinTable(name=“user\u state”)
私人名单国家;
此代码适用于:
class Example {
@Test
public void workingTest() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("testPU");
EntityManager em = emf.createEntityManager();
// Creating three states
State alabama = new State(state: 'Alabama');
State louisiana = new State(state: 'Louisiana');
State texas = new State(state: 'Texas');
em.getTransaction().begin();
em.persist(alabama);
em.persist(louisiana);
em.persist(texas);
em.getTransaction().commit();
List<State> states = em.createQuery('FROM State').getResultList();
// Assert only three states on DB
assert states.size() == 3;
User userFromAlabama = new User();
User userFromAlabamaAndTexas = new User();
em.getTransaction().begin();
State alabamaFromDB = em.find(State, alabama.getId());
State texasFromDB = em.find(State, texas.getId());
userFromAlabama.getStates().add(alabamaFromDB);
userFromAlabamaAndTexas.getStates().add(alabamaFromDB);
userFromAlabamaAndTexas.getStates().add(texasFromDB);
em.persist(userFromAlabama);
em.persist(userFromAlabamaAndTexas);
em.getTransaction().commit();
states = em.createQuery('FROM State').getResultList();
// Assert only three states on DB again
assert states.size() == 3;
// Assert one user
User userFromDB = em.find(User, userFromAlabama.getId());
assert userFromDB.getStates().size() == 1;
userFromDB = em.find(User, userFromAlabamaAndTexas.getId());
assert userFromDB.getStates().size() == 2;
}
}
@Entity
@Table(name="tbl_users")
class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id
@Column(name="user_name")
private String name
@ManyToMany
private Collection<State> states = Lists.newArrayList()
// Getters and setters
}
@Entity
@Table(name="tbl_states")
class State {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name="state")
private String state;
// Getters and setters
}
类示例{
@试验
公共无效工作测试(){
EntityManagerFactory emf=Persistence.createEntityManagerFactory(“testPU”);
EntityManager em=emf.createEntityManager();
//创建三个国家
阿拉巴马州=新州(州:“阿拉巴马”);
路易斯安那州=新州(州:“路易斯安那”);
德克萨斯州=新州(州:“德克萨斯”);
em.getTransaction().begin();
em.persist(阿拉巴马州);
em.persist(路易斯安那州);
em.persist(德克萨斯州);
em.getTransaction().commit();
List states=em.createQuery('FROM State').getResultList();
//在DB上仅断言三个状态
断言状态。大小()==3;
User userFromAlabama=新用户();
User USERFROMALABAMANDTEXAS=新用户();
em.getTransaction().begin();
State-alabamaFromDB=em.find(State,alabama.getId());
State texasFromDB=em.find(State,texas.getId());
userFromAlabama.getStates().add(alabamaFromDB);
userFromAlabamaAndTexas.getStates().add(alabamaFromDB);
UserFromAlabaMandTexas.getStates().add(texasFromDB);
em.persist(用户来自阿拉巴马州);
em.persist(来自阿拉巴马州和德克萨斯州的用户);
em.getTransaction().commit();
states=em.createQuery('FROM State').getResultList();
//再次在DB上仅断言三个状态
断言状态。大小()==3;
//断言一个用户
User userFromDB=em.find(User,userFromAlabama.getId());
断言userFromDB.getStates().size()==1;
userFromDB=em.find(User,userFromAlabamaAndTexas.getId());
断言userFromDB.getStates().size()==2;
}
}
@实体
@表(name=“tbl\U用户”)
类用户{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
私有整数id
@列(name=“user\u name”)
私有字符串名
@许多
私有集合状态=Lists.newArrayList()
//接球手和接球手
}
@实体
@表(name=“tbl_州”)
阶级国家{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
私有int-id;
@列(name=“state”)
私有字符串状态;
//接球手和接球手
}
您应该将映射更改为@ManyToMany
数据库上必须有3个表,如下所示:
TBL_用户、TBL_州和TBL_用户TBL_州
TBL_USERS_TBL_STATES表是Hibernate在使用@ManyToMany注释属性时使用的默认表名。如果要更改TBL_用户\u TBL_状态的表名,也可以使用@JoinTable注释。见文件
使用此配置,您应该能够从数据库中获取状态,将其添加到新用户,然后将其持久化。我做了一个单元测试,它工作了 如何在将状态对象添加到用户对象之前检索它们?@AbassA我对每个对象执行一个getStateById(),它将状态对象返回到数组列表中,然后使用setter方法将该数组列表添加到用户。您可以提供处理save方法的完整代码吗。为什么在集合属性的顶部有一个@Column,您不需要这个,我想您有一个表用户_state,它支持关系?@AbassA在前端或后端?在后端,您用于保存的代码和使用getStateById方法的地方这不起作用,它一直在一次创建多个用户?例如,如果我选择2个状态,它将创建2个具有相同详细信息(id除外)的用户,可能您的保存逻辑不正确,请添加您所有业务代码的帖子详细信息,我需要完整的图片。从用户实例化或加载到持久化和刷新到数据库,包括adduser方法周围的代码。你是说要删除到@OneToMany配置吗?是的,因为你不需要它。您真正需要的是确保数据库中存在中间表“TBL\u USERS\u TBL\u STATES”。Hibernate将使用此表映射用户的状态(状态集合)!服务id?此字段在哪里?抱歉,它应该显示state_idorg.postgresql.util.PSQLException:错误:重复键值违反唯一约束“uk_g6pr701i2pcq7400xrlb0hns”2017-07-07T19:14:07.462969+00:00应用程序[web.1]:详细信息:键(state_id)=(2)已存在。
class Example {
@Test
public void workingTest() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("testPU");
EntityManager em = emf.createEntityManager();
// Creating three states
State alabama = new State(state: 'Alabama');
State louisiana = new State(state: 'Louisiana');
State texas = new State(state: 'Texas');
em.getTransaction().begin();
em.persist(alabama);
em.persist(louisiana);
em.persist(texas);
em.getTransaction().commit();
List<State> states = em.createQuery('FROM State').getResultList();
// Assert only three states on DB
assert states.size() == 3;
User userFromAlabama = new User();
User userFromAlabamaAndTexas = new User();
em.getTransaction().begin();
State alabamaFromDB = em.find(State, alabama.getId());
State texasFromDB = em.find(State, texas.getId());
userFromAlabama.getStates().add(alabamaFromDB);
userFromAlabamaAndTexas.getStates().add(alabamaFromDB);
userFromAlabamaAndTexas.getStates().add(texasFromDB);
em.persist(userFromAlabama);
em.persist(userFromAlabamaAndTexas);
em.getTransaction().commit();
states = em.createQuery('FROM State').getResultList();
// Assert only three states on DB again
assert states.size() == 3;
// Assert one user
User userFromDB = em.find(User, userFromAlabama.getId());
assert userFromDB.getStates().size() == 1;
userFromDB = em.find(User, userFromAlabamaAndTexas.getId());
assert userFromDB.getStates().size() == 2;
}
}
@Entity
@Table(name="tbl_users")
class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id
@Column(name="user_name")
private String name
@ManyToMany
private Collection<State> states = Lists.newArrayList()
// Getters and setters
}
@Entity
@Table(name="tbl_states")
class State {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name="state")
private String state;
// Getters and setters
}