java - 创建三个实体时传递的分离实体持续出现错误
问题描述
我有 3 个实体CustomerDetails
,AddressLine
并且Bankdetails
. 当我尝试使用在 h2 db 中创建条目时CrudRepository
,它会抛出一个错误,将一个声明为分离实体。谁能告诉我为什么会抛出这个错误?
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: com.ABC.AAP.Domain.Address
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:120) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:113) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:745) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:713) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.engine.spi.CascadingActions$7.cascade(CascadingActions.java:298) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:492) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:416) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:218) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:151) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:427) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:264) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:135) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:185) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:55) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:721) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:707) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:314) ~[spring-orm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at com.sun.proxy.$Proxy77.persist(Unknown Source) ~[na:na]
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:554) ~[spring-data-jpa-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.data.repository.core.support.ImplementationInvocationMetadata.invoke(ImplementationInvocationMetadata.java:72) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:382) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:205) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:549) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:155) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130) ~[spring-data-commons-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367) ~[spring-tx-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118) ~[spring-tx-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.2.8.RELEASE.jar:5.2.8.RELEASE]
... 21 common frames omitted
在创建实体时会引发此错误。 org.hibernate.PersistentObjectException:分离的实体传递给坚持:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity
public class BankDetails {
@Id
@GeneratedValue (strategy = GenerationType.AUTO)
private long id;
private String bank_name;
private String account_number;
private String ifsc_code;
private String party_account_type;
@OneToOne(mappedBy = "bank_details") private CustomerDetails
customer_details;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BankDetails other = (BankDetails) obj;
if (id != other.id)
return false;
return true;
}
public BankDetails(String bank_name, String account_number, String ifsc_code, String party_account_type) {
super();
this.bank_name = bank_name;
this.account_number = account_number;
this.ifsc_code = ifsc_code;
this.party_account_type = party_account_type;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getBank_name() {
return bank_name;
}
public void setBank_name(String bank_name) {
this.bank_name = bank_name;
}
public String getAccount_number() {
return account_number;
}
public void setAccount_number(String account_number) {
this.account_number = account_number;
}
public String getIfsc_code() {
return ifsc_code;
}
public void setIfsc_code(String ifsc_code) {
this.ifsc_code = ifsc_code;
}
public String getParty_account_type() {
return party_account_type;
}
public void setParty_account_type(String party_account_type) {
this.party_account_type = party_account_type;
}
}
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
@Entity
public class CustomerDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String party_code;
private String title;
private String first_name;
private String last_name;
private String sex;
private String nationality;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="address_id",referencedColumnName = "id") private Address
addressline;
private String mobile_number;
private String email_id;
private String party_occupation;
private String pan_number;
private String tan_number;
private Date date_of_birth;
private String business_type;
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="bank_details_id",referencedColumnName = "id")
private BankDetails bank_details;
public CustomerDetails(String party_code, String title, String first_name, String last_name, String sex,
String nationality, Address addressline, String mobile_number, String email_id, String party_occupation,
String pan_number, String tan_number, Date date_of_birth, String business_type, BankDetails bank_details) {
super();
this.party_code = party_code;
this.title = title;
this.first_name = first_name;
this.last_name = last_name;
this.sex = sex;
this.nationality = nationality;
this.addressline = addressline;
this.mobile_number = mobile_number;
this.email_id = email_id;
this.party_occupation = party_occupation;
this.pan_number = pan_number;
this.tan_number = tan_number;
this.date_of_birth = date_of_birth;
this.business_type = business_type;
this.bank_details = bank_details;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CustomerDetails other = (CustomerDetails) obj;
if (id != other.id)
return false;
return true;
}
public String getParty_code() {
return party_code;
}
public void setParty_code(String party_code) {
this.party_code = party_code;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getFirst_name() {
return first_name;
}
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getNationality() {
return nationality;
}
public void setNationality(String nationality) {
this.nationality = nationality;
}
/*
* public Address getAddressline() { return addressline; }
*
* public void setAddressline(Address addressline) { this.addressline =
* addressline; }
*/
public String getMobile_number() {
return mobile_number;
}
public void setMobile_number(String mobile_number) {
this.mobile_number = mobile_number;
}
public String getEmail_id() {
return email_id;
}
public void setEmail_id(String email_id) {
this.email_id = email_id;
}
public String getParty_occupation() {
return party_occupation;
}
public void setParty_occupation(String party_occupation) {
this.party_occupation = party_occupation;
}
public String getPan_number() {
return pan_number;
}
public void setPan_number(String pan_number) {
this.pan_number = pan_number;
}
public String getTan_number() {
return tan_number;
}
public void setTan_number(String tan_number) {
this.tan_number = tan_number;
}
public Date getDate_of_birth() {
return date_of_birth;
}
public void setDate_of_birth(Date date_of_birth) {
this.date_of_birth = date_of_birth;
}
public String getBusiness_type() {
return business_type;
}
public void setBusiness_type(String business_type) {
this.business_type = business_type;
}
public BankDetails getBank_details() {
return bank_details;
}
public void setBank_details(BankDetails bank_details) {
this.bank_details = bank_details;
}
}
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@OneToOne(mappedBy = "addressline") private CustomerDetails customer_details;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Address other = (Address) obj;
if (id != other.id)
return false;
return true;
}
private String address1;
private String address2;
private String city;
private String state;
private String country;
private String pincode;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Address(String address1, String address2, String city, String state, String country, String pincode) {
super();
this.address1 = address1;
this.address2 = address2;
this.city = city;
this.state = state;
this.country = country;
this.pincode = pincode;
}
public String getAddress1() {
return address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
public String getAddress2() {
return address2;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getPincode() {
return pincode;
}
public void setPincode(String pincode) {
this.pincode = pincode;
}
}
** 已解决的问题:问题是由于创建条目期间的级联类型造成的。我使用的是 CascadeType.ALL,但是当更改为 CascadeType.MERGE 时,它就解决了。
解决方案
我相信问题出在实体中,如果你自己添加 ID,休眠认为这个实体已经在数据库中,对他来说它是分离的实体。
提示:尽量不要使用 GenerationType.AUTO,而是使用 SEQUENCE 或 IDENTITY 的更好方法。
AUTO - 我们将 ID 创建策略委托给持久性提供者,这并不总是最好的方法。
https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/GenerationType.html更多关于策略的信息。
推荐阅读
- django - 如何为带有翻译的 django rest 框架模型创建自定义序列化程序
- python - 在二维数组中查找字符串并将它们转换为浮点数 [Python]
- java - ID 生成器比较
- business-objects - Web Intelligence:限制块中的行数
- python - “没有名为 dgl 的模块”,但该模块有效
- dictionary - 使用 Ansible set_fact 从寄存器结果 systemctl 创建字典
- angular - Angular Reactive forms - 来自异步调用的值不更新表单
- node.js - 无法连接到伊蚊 MQTT 代理
- junit - 论据不同!需要:实际调用有不同的参数:
- javascript - Validating React form in componentDidUpdate()