Java 向数据库添加多个实例

Java 向数据库添加多个实例,java,hibernate,Java,Hibernate,我有一个简单的JSF+Hibernate+Spring+Mysql java应用程序,我在Tomcat7上运行它。在JSF视图页面上,它只有一个add按钮,可以通过单击它将实例添加到数据库中。它在添加第一个实例时运行得非常好。但是,当我尝试在同一个会话中添加一个实例时,程序失败,出现以下错误: An Error Occurred: org.hibernate.PersistentObjectException: detached entity passed to persist: com.

我有一个简单的JSF+Hibernate+Spring+Mysql java应用程序,我在Tomcat7上运行它。在JSF视图页面上,它只有一个add按钮,可以通过单击它将实例添加到数据库中。它在添加第一个实例时运行得非常好。但是,当我尝试在同一个会话中添加一个实例时,程序失败,出现以下错误:

  An Error Occurred:

org.hibernate.PersistentObjectException: detached entity passed to persist: com.springhibernatejsf.model.Person
在谷歌搜索了这个错误后,我发现可能是由于模式类中的
@GeneratedValue(strategy=GenerationType.IDENTITY)
而不是
@GeneratedValue(strategy=GenerationType.AUTO)
,或者在DAO实现类中使用了
session.persist()
而不是
session.merge()
,但是,他们两个都不为我工作

Person.java:

package com.springhibernatejsf.model;

import java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * Entity bean with JPA annotations
 * 
 *
 */
@Entity
@Table(name="Person")
@ManagedBean(name="person")
@SessionScoped
public class Person implements Serializable{
    @Id
    @Column(name="id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;

    private String name;

    private String country;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }
}
PersonDAOImpl.java:

package com.springhibernatejsf.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;

import com.springhibernatejsf.model.Person;

@Repository
public class PersonDAOImpl implements PersonDAO {

    private SessionFactory sessionFactory;

    private static final Logger logger = LoggerFactory.getLogger(PersonDAOImpl.class);

    public void setSessionFactory(SessionFactory sf){
        this.sessionFactory = sf;
    }
    @Override
    public void addPerson(Person p){
        Session session = this.sessionFactory.getCurrentSession();
        session.persist(p);
        session.flush();
        logger.info("Addition is successful!");
    }
    @SuppressWarnings("unchecked")
    @Override
    public List<Person> listPersons() {
        Session session = this.sessionFactory.getCurrentSession();
        List<Person> personsList = session.createQuery("from Person").list();
        for(Person p : personsList){
        }
        return personsList;
    }
}
package com.springhibernatejsf.dao;
导入java.util.List;
导入org.hibernate.Session;
导入org.hibernate.SessionFactory;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
导入org.springframework.stereotype.Repository;
导入com.springhibernatejsf.model.Person;
@存储库
公共类persondaimpl实现PersonDAO{
私人会话工厂会话工厂;
私有静态最终记录器Logger=LoggerFactory.getLogger(PersonDAOImpl.class);
公共无效设置会话工厂(会话工厂sf){
this.sessionFactory=sf;
}
@凌驾
公众人士(p人){
会话会话=this.sessionFactory.getCurrentSession();
会议记录(p);
session.flush();
logger.info(“添加成功!”);
}
@抑制警告(“未选中”)
@凌驾
公众人士名单{
会话会话=this.sessionFactory.getCurrentSession();
List personsList=session.createQuery(“来自个人”).List();
对于(人员p:人员列表){
}
返回人员列表;
}
}

为什么会出现这种情况?

请在
persondaimpl
中为
addPerson()尝试以下代码


问题是
persist()
必须在
transaction
边界内使用。

感谢您的回复。但在添加第二个实例后,我出现了相同的错误。
persist
操作用于全新的瞬态对象,如果已经分配了id,则会失败。在您的情况下,您可能希望调用
saveOrUpdate
而不是
persist
。我调用了saveOrUpdate,但没有任何更改。
public void addPerson(Person p){
        Session session = this.sessionFactory.getCurrentSession();
        Transaction transaction=session.beginTransaction();
        session.persist(p);
        session.flush();
        logger.info("Addition is successful!");
        transaction.commit();
    }