Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将对象A中的对象添加到对象B中而不创建新对象?冬眠_Java_Hibernate_One To Many_Hibernate Mapping_Cascade - Fatal编程技术网

Java 将对象A中的对象添加到对象B中而不创建新对象?冬眠

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

假设我有两个对象,一个是用户对象,另一个是状态对象。州的目标基本上是美国的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
}
用于添加用户的代码(使用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
}