"org.hibernate.PersistentObjectException: detached entity passed to persist" 无法解决的错误
"org.hibernate.PersistentObjectException: detached entity passed to persist" error that I can't work my head around
我最近开始在一个学校项目中使用 JPA 和 Hibernate,它基本上将大洲、国家和城市存储在数据库中。
尝试在实体上使用 persist 方法时,出现标题中提到的错误。
我访问过的任何线程都解决了很多更复杂的问题,并且对我的情况没有真正帮助。我希望通过在这里发帖找到一些指导。
这是数据库创建脚本。这是一个 PostgreSQL 数据库。
create table continents(
id integer primary key,
name varchar
);
create table countries(
id integer primary key,
name varchar,
code varchar,
continent_ID integer,
constraint fk_continents
foreign key (continent_ID)
references continents(id)
);
create table cities(
id integer primary key,
country_ID integer,
name varchar,
hasCapital boolean,
latitude float,
longitude float,
constraint fk_countries
foreign key (country_ID)
references countries(id)
);
基本上,国家table使用大陆table的ID作为外键,城市table再次使用国家table的ID , 作为外键。
我得到的错误是因为我试图坚持一个新的大陆实体。这是执行的代码:
public static void main(String[] args) {
EntityManagerFactory ef = Persistence.createEntityManagerFactory("default");
EntityManager em = ef.createEntityManager();
EntityTransaction transaction = em.getTransaction();
try{
transaction.begin();
ContinentsEntity continentEntity = new ContinentsEntity();
continentEntity.setId(1);
continentEntity.setName("Europe");
em.persist(continentEntity);
transaction.commit();
} finally {
if(transaction.isActive()){
transaction.rollback();
}
em.close();
ef.close();
}
}
所有实体 类 都是由 Intellij 通过持久化工具生成的。
这是类。
大陆实体:
package entity;
import javax.persistence.*;
@Entity
@Table(name = "continents", schema = "public", catalog = "postgres")
public class ContinentsEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id")
private int id;
@Basic
@Column(name = "name")
private String name;
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;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ContinentsEntity that = (ContinentsEntity) o;
if (id != that.id) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
return true;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
}
国家实体:
package entity;
import javax.persistence.*;
@Entity
@Table(name = "countries", schema = "public", catalog = "postgres")
public class CountriesEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id")
private int id;
@Basic
@Column(name = "name")
private String name;
@Basic
@Column(name = "code")
private String code;
@Basic
@Column(name = "continent_id")
private Integer continentId;
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 getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Integer getContinentId() {
return continentId;
}
public void setContinentId(Integer continentId) {
this.continentId = continentId;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CountriesEntity that = (CountriesEntity) o;
if (id != that.id) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
if (code != null ? !code.equals(that.code) : that.code != null) return false;
if (continentId != null ? !continentId.equals(that.continentId) : that.continentId != null) return false;
return true;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (code != null ? code.hashCode() : 0);
result = 31 * result + (continentId != null ? continentId.hashCode() : 0);
return result;
}
}
城市实体:
package entity;
import javax.persistence.*;
@Entity
@Table(name = "cities", schema = "public", catalog = "postgres")
public class CitiesEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id")
private int id;
@Basic
@Column(name = "country_id")
private Integer countryId;
@Basic
@Column(name = "name")
private String name;
@Basic
@Column(name = "hascapital")
private Boolean hascapital;
@Basic
@Column(name = "latitude")
private Double latitude;
@Basic
@Column(name = "longitude")
private Double longitude;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Integer getCountryId() {
return countryId;
}
public void setCountryId(Integer countryId) {
this.countryId = countryId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getHascapital() {
return hascapital;
}
public void setHascapital(Boolean hascapital) {
this.hascapital = hascapital;
}
public Double getLatitude() {
return latitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CitiesEntity that = (CitiesEntity) o;
if (id != that.id) return false;
if (countryId != null ? !countryId.equals(that.countryId) : that.countryId != null) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
if (hascapital != null ? !hascapital.equals(that.hascapital) : that.hascapital != null) return false;
if (latitude != null ? !latitude.equals(that.latitude) : that.latitude != null) return false;
if (longitude != null ? !longitude.equals(that.longitude) : that.longitude != null) return false;
return true;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + (countryId != null ? countryId.hashCode() : 0);
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (hascapital != null ? hascapital.hashCode() : 0);
result = 31 * result + (latitude != null ? latitude.hashCode() : 0);
result = 31 * result + (longitude != null ? longitude.hashCode() : 0);
return result;
}
}
这可能与我的数据库设计有关,或者 Intellij 生成我的实体的方式 类,但我就是想不通。
编辑:我的数据库设计是错误的,而且我试图保留 id。我将所有 pk 修改为串行,并删除了我添加 id 的代码行,这样就成功了。
问题是,您正在尝试保留一个设置了 id 的实体,而 Hibernate 认为它是一个现有实体,但无法在其持久性上下文中找到它。尝试持久化没有ID的实体,它应该是自动生成的。
我最近开始在一个学校项目中使用 JPA 和 Hibernate,它基本上将大洲、国家和城市存储在数据库中。
尝试在实体上使用 persist 方法时,出现标题中提到的错误。
我访问过的任何线程都解决了很多更复杂的问题,并且对我的情况没有真正帮助。我希望通过在这里发帖找到一些指导。
这是数据库创建脚本。这是一个 PostgreSQL 数据库。
create table continents(
id integer primary key,
name varchar
);
create table countries(
id integer primary key,
name varchar,
code varchar,
continent_ID integer,
constraint fk_continents
foreign key (continent_ID)
references continents(id)
);
create table cities(
id integer primary key,
country_ID integer,
name varchar,
hasCapital boolean,
latitude float,
longitude float,
constraint fk_countries
foreign key (country_ID)
references countries(id)
);
基本上,国家table使用大陆table的ID作为外键,城市table再次使用国家table的ID , 作为外键。
我得到的错误是因为我试图坚持一个新的大陆实体。这是执行的代码:
public static void main(String[] args) {
EntityManagerFactory ef = Persistence.createEntityManagerFactory("default");
EntityManager em = ef.createEntityManager();
EntityTransaction transaction = em.getTransaction();
try{
transaction.begin();
ContinentsEntity continentEntity = new ContinentsEntity();
continentEntity.setId(1);
continentEntity.setName("Europe");
em.persist(continentEntity);
transaction.commit();
} finally {
if(transaction.isActive()){
transaction.rollback();
}
em.close();
ef.close();
}
}
所有实体 类 都是由 Intellij 通过持久化工具生成的。
这是类。
大陆实体:
package entity;
import javax.persistence.*;
@Entity
@Table(name = "continents", schema = "public", catalog = "postgres")
public class ContinentsEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id")
private int id;
@Basic
@Column(name = "name")
private String name;
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;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ContinentsEntity that = (ContinentsEntity) o;
if (id != that.id) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
return true;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
}
国家实体:
package entity;
import javax.persistence.*;
@Entity
@Table(name = "countries", schema = "public", catalog = "postgres")
public class CountriesEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id")
private int id;
@Basic
@Column(name = "name")
private String name;
@Basic
@Column(name = "code")
private String code;
@Basic
@Column(name = "continent_id")
private Integer continentId;
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 getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Integer getContinentId() {
return continentId;
}
public void setContinentId(Integer continentId) {
this.continentId = continentId;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CountriesEntity that = (CountriesEntity) o;
if (id != that.id) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
if (code != null ? !code.equals(that.code) : that.code != null) return false;
if (continentId != null ? !continentId.equals(that.continentId) : that.continentId != null) return false;
return true;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (code != null ? code.hashCode() : 0);
result = 31 * result + (continentId != null ? continentId.hashCode() : 0);
return result;
}
}
城市实体:
package entity;
import javax.persistence.*;
@Entity
@Table(name = "cities", schema = "public", catalog = "postgres")
public class CitiesEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id")
private int id;
@Basic
@Column(name = "country_id")
private Integer countryId;
@Basic
@Column(name = "name")
private String name;
@Basic
@Column(name = "hascapital")
private Boolean hascapital;
@Basic
@Column(name = "latitude")
private Double latitude;
@Basic
@Column(name = "longitude")
private Double longitude;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Integer getCountryId() {
return countryId;
}
public void setCountryId(Integer countryId) {
this.countryId = countryId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getHascapital() {
return hascapital;
}
public void setHascapital(Boolean hascapital) {
this.hascapital = hascapital;
}
public Double getLatitude() {
return latitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CitiesEntity that = (CitiesEntity) o;
if (id != that.id) return false;
if (countryId != null ? !countryId.equals(that.countryId) : that.countryId != null) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
if (hascapital != null ? !hascapital.equals(that.hascapital) : that.hascapital != null) return false;
if (latitude != null ? !latitude.equals(that.latitude) : that.latitude != null) return false;
if (longitude != null ? !longitude.equals(that.longitude) : that.longitude != null) return false;
return true;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + (countryId != null ? countryId.hashCode() : 0);
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (hascapital != null ? hascapital.hashCode() : 0);
result = 31 * result + (latitude != null ? latitude.hashCode() : 0);
result = 31 * result + (longitude != null ? longitude.hashCode() : 0);
return result;
}
}
这可能与我的数据库设计有关,或者 Intellij 生成我的实体的方式 类,但我就是想不通。
编辑:我的数据库设计是错误的,而且我试图保留 id。我将所有 pk 修改为串行,并删除了我添加 id 的代码行,这样就成功了。
问题是,您正在尝试保留一个设置了 id 的实体,而 Hibernate 认为它是一个现有实体,但无法在其持久性上下文中找到它。尝试持久化没有ID的实体,它应该是自动生成的。